# Copyright (c) 2018 Mycroft AI, Inc.
#
# This file is part of Mycroft Skills Kit
# (see https://github.com/MycroftAI/mycroft-skills-kit).
#
# Licensed 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.
#
from argparse import ArgumentParser
from genericpath import samefile
from git import Git
from github.Repository import Repository
from msm import MycroftSkillsManager

from msk.console_action import ConsoleAction
from msk.exceptions import NotUploaded
from msk.repo_action import SkillData
from msk.util import skills_kit_footer, create_or_edit_pr

body_template = (
    """
This upgrades {skill_name} to include the following new commits:

{commits}

"""
    + skills_kit_footer
)


class UpgradeAction(ConsoleAction):
    def __init__(self, args):
        msm = MycroftSkillsManager()
        skill_matches = [
            skill
            for skill in msm.list()
            if skill.is_local and samefile(skill.path, args.skill_folder)
        ]
        if not skill_matches:
            raise NotUploaded(
                "Skill at folder not uploaded to store: "
                f"{args.skill_folder}"
            )

        self.skill = SkillData(skill_matches[0])
        self.skill.init_existing()  # Verifies the skill exists

    @staticmethod
    def register(parser: ArgumentParser):
        pass  # Implemented in SubmitAction

    def create_pr_message(
        self, skill_git: Git, skill_repo: Repository
    ) -> tuple:
        """Create a list of changes for PR content from git commits."""
        title = "Upgrade " + self.skill.name
        body = body_template.format(
            skill_name=self.skill.name,
            commits="\n".join(
                " - [{}]({})".format(
                    skill_git.show("-s", sha, format="%s"),
                    skill_repo.get_commit(sha).html_url,
                )
                for sha in skill_git.rev_list(
                    "--ancestry-path",
                    "{}..{}".format(self.skill.entry.sha, "HEAD"),
                ).split("\n")
            ),
        )
        return title, body

    def perform(self):
        print("Upgrading an existing skill in the skill repo...")
        upgrade_branch = self.skill.upgrade()
        self.repo.push_to_fork(upgrade_branch)
        title, body = self.create_pr_message(self.skill.git, self.skill.hub)
        print()
        print("===", title, "===")
        print(body)
        print()
        pull = create_or_edit_pr(
            title, body, self.repo.hub, self.user, upgrade_branch, self.branch
        )
        print("Created PR at:", pull.html_url)
