# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.

import os
import shlex
from pathlib import Path
from functools import partial
import tempfile

import click
import github

from .utils.git import git
from .utils.logger import logger
from .crossbow import Repo, Queue, Config, Target, Job, CommentReport


class EventError(Exception):
    pass


class CommandError(Exception):

    def __init__(self, message):
        self.message = message


class _CommandMixin:

    def get_help_option(self, ctx):
        def show_help(ctx, param, value):
            if value and not ctx.resilient_parsing:
                raise click.UsageError(ctx.get_help())
        option = super().get_help_option(ctx)
        option.callback = show_help
        return option

    def __call__(self, message, **kwargs):
        args = shlex.split(message)
        try:
            with self.make_context(self.name, args=args, obj=kwargs) as ctx:
                return self.invoke(ctx)
        except click.ClickException as e:
            raise CommandError(e.format_message())


class Command(_CommandMixin, click.Command):
    pass


class Group(_CommandMixin, click.Group):

    def command(self, *args, **kwargs):
        kwargs.setdefault('cls', Command)
        return super().command(*args, **kwargs)

    def group(self, *args, **kwargs):
        kwargs.setdefault('cls', Group)
        return super().group(*args, **kwargs)

    def parse_args(self, ctx, args):
        if not args and self.no_args_is_help and not ctx.resilient_parsing:
            raise click.UsageError(ctx.get_help())
        return super().parse_args(ctx, args)


command = partial(click.command, cls=Command)
group = partial(click.group, cls=Group)


class CommentBot:

    def __init__(self, name, handler, token=None):
        # TODO(kszucs): validate
        assert isinstance(name, str)
        assert callable(handler)
        self.name = name
        self.handler = handler
        self.github = github.Github(token)

    def parse_command(self, payload):
        # only allow users of apache org to submit commands, for more see
        # https://developer.github.com/v4/enum/commentauthorassociation/
        allowed_roles = {'OWNER', 'MEMBER', 'CONTRIBUTOR'}
        mention = '@{}'.format(self.name)
        comment = payload['comment']

        if payload['sender']['login'] == self.name:
            raise EventError("Don't respond to itself")
        elif payload['action'] not in {'created', 'edited'}:
            raise EventError("Don't respond to comment deletion")
        elif comment['author_association'] not in allowed_roles:
            raise EventError(
                "Don't respond to comments from non-authorized users"
            )
        elif not comment['body'].lstrip().startswith(mention):
            raise EventError("The bot is not mentioned")

        return payload['comment']['body'].split(mention)[-1].strip()

    def handle(self, event, payload):
        try:
            command = self.parse_command(payload)
        except EventError as e:
            logger.error(e)
            # see the possible reasons in the validate method
            return

        if event == 'issue_comment':
            return self.handle_issue_comment(command, payload)
        elif event == 'pull_request_review_comment':
            return self.handle_review_comment(command, payload)
        else:
            raise ValueError("Unexpected event type {}".format(event))

    def handle_issue_comment(self, command, payload):
        repo = self.github.get_repo(payload['repository']['id'], lazy=True)
        issue = repo.get_issue(payload['issue']['number'])

        try:
            pull = issue.as_pull_request()
        except github.GithubException:
            return issue.create_comment(
                "The comment bot only listens to pull request comments!"
            )

        comment = pull.get_issue_comment(payload['comment']['id'])
        try:
            self.handler(command, issue=issue, pull_request=pull,
                         comment=comment)
        except CommandError as e:
            logger.error(e)
            pull.create_issue_comment("```\n{}\n```".format(e.message))
        except Exception as e:
            logger.exception(e)
            comment.create_reaction('-1')
        else:
            comment.create_reaction('+1')

    def handle_review_comment(self, payload):
        raise NotImplementedError()


@group(name='@github-actions')
@click.pass_context
def actions(ctx):
    """Ursabot"""
    ctx.ensure_object(dict)


@actions.group()
@click.option('--crossbow', '-c', default='ursacomputing/crossbow',
              help='Crossbow repository on github to use')
@click.pass_obj
def crossbow(obj, crossbow):
    """
    Trigger crossbow builds for this pull request
    """
    obj['crossbow_repo'] = crossbow


def _clone_arrow_and_crossbow(dest, crossbow_repo, pull_request):
    """
    Clone the repositories and initialize crossbow objects.

    Parameters
    ----------
    dest : Path
        Filesystem path to clone the repositories to.
    crossbow_repo : str
        Github repository name, like kszucs/crossbow.
    pull_request : pygithub.PullRequest
        Object containing information about the pull request the comment bot
        was triggered from.
    """
    arrow_path = dest / 'arrow'
    queue_path = dest / 'crossbow'

    # clone arrow and checkout the pull request's branch
    pull_request_ref = 'pull/{}/head:{}'.format(
        pull_request.number, pull_request.head.ref
    )
    git.clone(pull_request.base.repo.clone_url, str(arrow_path))
    git.fetch('origin', pull_request_ref, git_dir=arrow_path)
    git.checkout(pull_request.head.ref, git_dir=arrow_path)

    # clone crossbow repository
    crossbow_url = 'https://github.com/{}'.format(crossbow_repo)
    git.clone(crossbow_url, str(queue_path))

    # initialize crossbow objects
    github_token = os.environ['CROSSBOW_GITHUB_TOKEN']
    arrow = Repo(arrow_path)
    queue = Queue(queue_path, github_token=github_token, require_https=True)

    return (arrow, queue)


@crossbow.command()
@click.argument('tasks', nargs=-1, required=False)
@click.option('--group', '-g', 'groups', multiple=True,
              help='Submit task groups as defined in tests.yml')
@click.option('--param', '-p', 'params', multiple=True,
              help='Additional task parameters for rendering the CI templates')
@click.option('--arrow-version', '-v', default=None,
              help='Set target version explicitly.')
@click.pass_obj
def submit(obj, tasks, groups, params, arrow_version):
    """
    Submit crossbow testing tasks.

    See groups defined in arrow/dev/tasks/tests.yml
    """
    crossbow_repo = obj['crossbow_repo']
    pull_request = obj['pull_request']
    with tempfile.TemporaryDirectory() as tmpdir:
        tmpdir = Path(tmpdir)
        arrow, queue = _clone_arrow_and_crossbow(
            dest=Path(tmpdir),
            crossbow_repo=crossbow_repo,
            pull_request=pull_request,
        )
        # load available tasks configuration and groups from yaml
        config = Config.load_yaml(arrow.path / "dev" / "tasks" / "tasks.yml")
        config.validate()

        # initialize the crossbow build's target repository
        target = Target.from_repo(arrow, version=arrow_version,
                                  remote=pull_request.head.repo.clone_url,
                                  branch=pull_request.head.ref)

        # parse additional job parameters
        params = dict([p.split("=") for p in params])

        # instantiate the job object
        job = Job.from_config(config=config, target=target, tasks=tasks,
                              groups=groups, params=params)

        # add the job to the crossbow queue and push to the remote repository
        queue.put(job, prefix="actions")
        queue.push()

        # render the response comment's content
        report = CommentReport(job, crossbow_repo=crossbow_repo)

        # send the response
        pull_request.create_issue_comment(report.show())
