#!/usr/bin/env python
#
# Copyright (C) 2019 The Android Open Source Project
#
# 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.
#
# pylint: disable=not-callable, relative-import, line-too-long, no-else-return

import argparse
import fileinput
import os.path as path
import re
import subprocess
import xml.etree.ElementTree as ET


def green_print(to_print):
    print("\033[92m" + to_print + "\033[0m")


def is_clang_project(element):
    return element.tag == "project" and \
           element.get("path") == "prebuilts-master/clang/host/linux-x86"


class KernelToolchainUpdater():

    def __init__(self):
        self.parse_args()
        self.get_clang_versions()
        self.get_clang_sha()
        self.kernel_dir = path.join(self.kernel_tree, "private", "msm-google")
        self.repo_dir = path.join(self.kernel_tree, ".repo", "manifests")
        self.topic = path.basename(self.kernel_tree) + "_" + self.clang_revision

        self.resync_tree()

        self.update_sha()
        self.commit_sha()
        self.push_manifest_change()

        self.resync_tree()

        self.update_kernel_toolchain()
        self.commit_kernel_toolchain()
        self.push_kernel_change()

    def parse_args(self):
        parser = argparse.ArgumentParser()
        # TODO: some validation of the command line args would be nice.
        parser.add_argument(
            "kernel_tree",
            help="Source directory of the repo checkout of the kernel.")
        parser.add_argument(
            "clang_bin", help="Path to the new clang binary in AOSP.")
        parser.add_argument(
            "bug_number",
            help="The bug number to be included in the commit message.")
        parser.add_argument(
            "-d", action="store_true", help="Dry run and debug.")
        args = parser.parse_args()
        self.bug_number = args.bug_number
        self.clang_bin = args.clang_bin
        self.kernel_tree = args.kernel_tree
        self.dry_run = args.d

    def get_clang_versions(self):
        output = subprocess.check_output([self.clang_bin, "--version"])
        self.clang_revision = re.search("based on (r[0-9]+[a-z]?)",
                                        output).groups()[0]
        self.clang_version = re.search("clang version ([0-9\.]+)",
                                       output).groups()[0]

    def get_clang_sha(self):
        clang_dir = path.dirname(self.clang_bin)
        output = subprocess.check_output(
            ["git", "--no-pager", "log", "-n", "1"], cwd=clang_dir)
        self.clang_sha = re.search("commit ([0-9a-z]+)", output).groups()[0]

    def update_sha(self):
        green_print("Updating SHA")
        xml_path = path.join(self.repo_dir, "default.xml")
        if self.dry_run:
            print("Updating %s to use\n%s." % (xml_path, self.clang_sha))
            return
        # It would be great to just use the builtin XML serializer/deserializer
        # in a sane way; unfortunately this will end up reformatting
        # indentation and reordering element attributes.
        for line in fileinput.input(xml_path, inplace=True):
            try:
                element = ET.fromstring(line)
                if is_clang_project(element):
                    line = re.sub("revision=\"[0-9a-z]+\"",
                                  "revision=\"%s\"" % self.clang_sha, line)
            except ET.ParseError:
                pass
            finally:
                print(line),

    def commit_sha(self):
        green_print("Committing SHA")
        message = """
Update Clang to %s based on %s

Bug: %s
""".strip() % (self.clang_version, self.clang_revision, self.bug_number)
        command = "git commit -asm"
        if self.dry_run:
            print(command + " \"" + message + "\"")
            return
        subprocess.check_output(
            command.split(" ") + [message], cwd=self.repo_dir)

    def push_manifest_change(self):
        green_print("Pushing manifest change")
        output = subprocess.check_output(["repo", "--no-pager", "info"],
                                         cwd=self.repo_dir)
        repo_branch = output.split("\n")[0].split(" ")[2]
        command = "git push origin HEAD:refs/for/%s -o topic=%s" % (repo_branch,
                                                                    self.topic)
        if self.dry_run:
            print(command)
            return
        subprocess.check_output(command.split(" "), cwd=self.repo_dir)

    def resync_tree(self):
        green_print("Syncing kernel tree")
        command = "repo sync -c --no-tags -q -j 71"
        if self.dry_run:
            print(command)
            return
        subprocess.check_output(command.split(" "), cwd=self.repo_dir)

    def update_kernel_toolchain(self):
        green_print("Updating kernel toolchain")
        # TODO: do all devices name this file `build.config.common`? (NO)
        config_path = path.join(self.kernel_dir, "build.config.common")
        if self.dry_run:
            print("Updating %s to use %s." % (config_path, self.clang_revision))
            return
        for line in fileinput.input(config_path, inplace=True):
            line = re.sub("clang-r[0-9a-b]+", "clang-" + self.clang_revision,
                          line)
            print(line),

    def commit_kernel_toolchain(self):
        green_print("Committing kernel toolchain")
        message = """
ANDROID: clang: update to %s

Bug: %s
""".strip() % (self.clang_version, self.bug_number)
        command = "git commit -asm"
        if self.dry_run:
            print(command + " \"" + message + "\"")
            return
        # TODO: it might be nice to `git checkout -b <topic>` before committing.
        subprocess.check_output(
            command.split(" ") + [message], cwd=self.kernel_dir)

    def push_kernel_change(self):
        green_print("Pushing kernel change")
        xml_path = path.join(self.repo_dir, "default.xml")
        remote = subprocess.check_output(["git", "--no-pager", "remote"],
                                         cwd=self.kernel_dir).strip()
        for project in ET.parse(xml_path).iter("project"):
            if (project.get("path") == "private/msm-google"):
                command = "git push %s HEAD:refs/for/%s -o topic=%s" % (
                    remote, project.get("revision"), self.topic)
                if self.dry_run:
                    print(command)
                    return
                subprocess.check_output(command.split(" "), cwd=self.kernel_dir)
                break


if __name__ == "__main__":
    KernelToolchainUpdater()
