__author__ = 'slaskawi@redhat.com'

import logging
from git import *


class GitRepositoryUpdater:
    def __init__(self, configuration):
        self._configuration = configuration
        self._product_repo = None
        self._packaging_repo = None

    def initialize_repositories(self):
        logging.info("Initializing Git repositories: %s %s", "jdg", "packaging")
        self._product_repo = Repo.init(self._configuration.get_productization_repo_location())
        self._packaging_repo = Repo.init(self._configuration.get_packaging_repo_location())

        if self._product_repo.remotes.__len__() < 2:
            logging.info("Adding remotes to repositories")
            self._product_repo.create_remote("jdg", self._configuration.get_upstream_repo_address())
            self._product_repo.create_remote("productization", self._configuration.get_product_repo_address())
            self._packaging_repo.create_remote("packaging", self._configuration.get_packaging_repo_address())
            logging.info("Fetching %s remotes", "product")
            self._product_repo.git.fetch(all=True)
            # self._product_repo.git.fetch(all=True, tags=True)
            logging.info("Fetching %s remotes", "packaging")
            self._packaging_repo.git.fetch(all=True)
            # self._packaging_repo.git.fetch(all=True, tags=True)

        self._product_repo.git.checkout("jdg/" + self._configuration.get_upstream_branch(), f=True,
                                        B=self._configuration.get_upstream_branch())
        self._packaging_repo.git.checkout("packaging/" + self._configuration.get_packaging_branch(), f=True,
                                          B=self._configuration.get_packaging_branch())

    def create_base_tag(self):
        logging.info("Tagging product repository with: %s", self._configuration.get_productization_base_tag())
        self._product_repo.git.tag(self._configuration.get_productization_base_tag(), f=True)

    def prepare_productized_repo_for_release(self):
        productization_branch = self._configuration.get_productization_branch()
        upstream_branch = self._configuration.get_upstream_branch()
        logging.info("Checking out prod branch: %s and rebasing against upstream: %s", productization_branch,
                     upstream_branch)
        self._product_repo.git.checkout("productization/" + productization_branch, f=True, B=productization_branch)
        self._product_repo.git.rebase("productization/" + upstream_branch,
                                      "productization/" + productization_branch + "^",
                                      onto="jdg/" + upstream_branch)
        self._product_repo.git.checkout(B=productization_branch)

    def commit_versions(self):
        commit_message = self._configuration.get_release_commit_message()
        logging.info("Committing changes to repositories, commit message: %s", commit_message)
        self._product_repo.git.commit(a=True, message=commit_message)
        self._packaging_repo.git.commit(a=True, message=commit_message)

    def tag_versions(self):
        tag_name = self._configuration.get_release_tag_name()
        logging.info("Tagging repositories, tag name: %s", tag_name)
        self._product_repo.git.tag(tag_name, f=True)
        self._packaging_repo.git.tag(tag_name, f=True)

    def push_to_productized_repos(self):
        productization_branch = self._configuration.get_productization_branch()
        packaging_branch = self._configuration.get_packaging_branch()
        release_tag = self._configuration.get_release_tag_name()
        base_tag = self._configuration.get_productization_base_tag()
        if self._configuration.get_dry_run() is True:
            logging.info("Pushing changes to repositories (dry run)")
            self._product_repo.git.push("productization", productization_branch, f=True, dry_run=True)
            self._packaging_repo.git.push("packaging", packaging_branch, dry_run=True)
            self._product_repo.git.push("productization", release_tag, dry_run=True)
            self._product_repo.git.push("productization", base_tag, dry_run=True)
            self._packaging_repo.git.push("packaging", release_tag, dry_run=True)
        else:
            logging.info("Pushing changes to repositories")
            self._product_repo.git.push("productization", productization_branch, f=True)
            self._packaging_repo.git.push("packaging", packaging_branch)
            self._product_repo.git.push("productization", release_tag)
            self._product_repo.git.push("productization", base_tag)
            self._packaging_repo.git.push("packaging", release_tag)
