# -*- coding: utf-8 -*-
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.

import datetime
import json

import click
import click_spinner
import slugid

import cli_common.taskcluster
import please_cli.config
import please_cli.utils

PROJECTS = list(set(please_cli.config.PROJECTS) - set(please_cli.config.DEV_PROJECTS))


def get_build_task(index,
                   project,
                   task_group_id,
                   parent_task,
                   github_commit,
                   owner,
                   channel,
                   taskcluster_secret,
                   cache_bucket=None,
                   cache_region=None,
                   ):

    command = [
        './please', '-vv', 'tools', 'build', project,
        '--taskcluster-secret=' + taskcluster_secret,
        '--no-interactive',
        '--task-group-id', task_group_id,
        '--github-commit', github_commit,
    ]

    nix_path_attributes = [project]
    deployments = please_cli.config.PROJECTS_CONFIG[project].get('deploys', [])
    for deployment in deployments:
        for channel in deployment['options']:
            if 'nix_path_attribute' in deployment['options'][channel]:
                nix_path_attributes.append('{}.{}'.format(
                    project,
                    deployment['options'][channel]['nix_path_attribute'],
                ))
    nix_path_attributes = list(set(nix_path_attributes))

    for nix_path_attribute in nix_path_attributes:
        command.append(f'--nix-path-attribute={nix_path_attribute}')

    if cache_bucket and cache_region:
        command += [
            f'--cache-bucket={cache_bucket}',
            f'--cache-region={cache_region}',
        ]
    return get_task(
        task_group_id,
        [parent_task],
        github_commit,
        channel,
        taskcluster_secret,
        ' '.join(command),
        {
            'name': '1.{index:02}. Building {project}'.format(
                index=index + 1,
                project=project,
            ),
            'description': '',
            'owner': owner,
            'source': 'https://github.com/mozilla/release-services/tree/' + channel,

        },
        max_run_time_in_hours=5,
    )


def get_deploy_task(index,
                    project,
                    project_requires,
                    deploy_target,
                    deploy_options,
                    task_group_id,
                    parent_task,
                    github_commit,
                    owner,
                    channel,
                    taskcluster_secret,
                    ):

    scopes = []

    nix_path_attribute = deploy_options.get('nix_path_attribute')
    if nix_path_attribute:
        nix_path_attribute = '{}.{}'.format(project, nix_path_attribute)
    else:
        nix_path_attribute = project

    if deploy_target == 'S3':
        subfolder = []
        if 'subfolder' in deploy_options:
            subfolder = [deploy_options['subfolder']]
        project_csp = []
        for url in deploy_options.get('csp', []):
            project_csp.append(f'--csp="{url}"')
        for require in project_requires:
            require_config = please_cli.config.PROJECTS_CONFIG.get(require, {})

            require_urls = [
                i.get('options', {}).get(channel, {}).get('url')
                for i in require_config.get('deploys', [])
            ]
            require_urls = filter(lambda x: x is not None, require_urls)
            require_urls = map(lambda x: '--csp="{}"'.format(x), require_urls)

            project_csp += require_urls

        project_envs = []
        project_envs.append('--env="release-version: {}"'.format(please_cli.config.VERSION))
        project_envs.append('--env="release-channel: {}"'.format(channel))
        for env_name, env_value in deploy_options.get('envs', {}).items():
            project_envs.append('--env="{}: {}"'.format(env_name, env_value))
        for require in project_requires:
            require_config = please_cli.config.PROJECTS_CONFIG.get(require, {})

            require_urls = [
                (
                    i.get('options', {}).get(channel, {}).get('url'),
                    i.get('options', {}).get(channel, {}).get('name-suffix', ''),
                )
                for i in require_config.get('deploys', [])
            ]
            require_urls = filter(lambda x: x[0] is not None, require_urls)
            normalized_require = please_cli.utils.normalize_name(require, normalizer='-')
            require_urls = map(lambda x: f'--env="{normalized_require}{x[1]}-url: {x[0]}"', require_urls)

            project_envs += require_urls

        project_name = '{}{} to AWS S3 ({})'.format(
            project,
            ' ({})'.format(nix_path_attribute),
            deploy_options['s3_bucket'],
        )
        command = [
            './please', '-vv',
            'tools', 'deploy:S3',
            project,
            '--s3-bucket=' + deploy_options['s3_bucket'],
            '--taskcluster-secret=' + taskcluster_secret,
            '--nix-path-attribute=' + nix_path_attribute,
            '--no-interactive',
        ] + subfolder + project_csp + project_envs

    elif deploy_target == 'HEROKU':
        project_name = '{}{} to HEROKU ({}/{})'.format(
            project,
            ' ({})'.format(nix_path_attribute),
            deploy_options['heroku_app'],
            deploy_options['heroku_dyno_type'],
        )
        command = [
            './please', '-vv',
            'tools', 'deploy:HEROKU',
    
        project,
            '--heroku-app=' + deploy_options['heroku_app'],
            '--heroku-dyno-type=' + deploy_options['heroku_dyno_type'],
        ]

        heroku_command = deploy_options.get('
heroku_command')
        if heroku_command:
            command.append(f'--heroku-command="{heroku_command}"')

        command += [
            '--taskcluster-secret=' + taskcluster_secret,
            '--nix-path-attribute=' + nix_path_attribute,
            '--no-interactive',
        ]

    elif deploy_target == 'DOCKERHUB':
        try:
            docker_registry = deploy_options['docker_registry']
            docker_repo = deploy_options['docker_repo']
            docker_stable_tag = deploy_options['docker_stable_tag']
        except KeyError:
            raise click.ClickException(
                'Missing `docker_registry` or `docker_repo` or `docker_stable_tag` in deploy options')

        project_name = (
            f'{project} ({nix_path_attribute}) to DOCKERHUB '
            f'({docker_registry}/{docker_repo}:{project}-{nix_path_attribute}-{channel})'
        )
        command = [
            './please', '-vv', 'tools', 'deploy:DOCKERHUB', project,
            f'--taskcluster-secret={taskcluster_secret}',
            f'--nix-path-attribute={nix_path_attribute}',
            f'--docker-repo={docker_repo}',
            f'--docker-registry={docker_registry}',
            f'--channel={channel}',
            f'--docker-stable-tag={docker_stable_tag}',
            '--no-interactive',
        ]

    elif deploy_target == 'TASKCLUSTER_HOOK':
        try:
            docker_registry = deploy_options['docker_registry']
            docker_repo = deploy_options['docker_repo']
            docker_stable_tag = deploy_options.get('docker_stable_tag')
        except KeyError:
            raise click.ClickException('Missing `docker_registry` or `docker_repo` in deploy options')
        hook_group_id = 'project-releng'
        name_suffix = deploy_options.get('name-suffix', '')
        hook_id = f'services-{channel}-{project}{name_suffix}'
        project_name = f'{project} ({nix_path_attribute}) to TASKCLUSTER HOOK ({hook_group_id}/{hook_id})'
        command = [
            './please', '-vv',
            'tools', 'deploy:TASKCLUSTER_HOOK',
            project,
            f'--docker-registry={docker_registry}',
            f'--docker-repo={docker_repo}',
            f'--hook-group-id={hook_group_id}',
            f'--hook-id={hook_id}',