# Copyright (C) 2008 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.

import sys

from color import Coloring
from command import InteractiveCommand
from git_command import GitCommand
from repo_logging import RepoLogger


logger = RepoLogger(__file__)


class _ProjectList(Coloring):
    def __init__(self, gc):
        Coloring.__init__(self, gc, "interactive")
        self.prompt = self.printer("prompt", fg="blue", attr="bold")
        self.header = self.printer("header", attr="bold")
        self.help = self.printer("help", fg="red", attr="bold")


class Stage(InteractiveCommand):
    COMMON = True
    helpSummary = "Stage file(s) for commit"
    helpUsage = """
%prog -i [<project>...]
"""
    helpDescription = """
The '%prog' command stages files to prepare the next commit.
"""

    def _Options(self, p):
        g = p.get_option_group("--quiet")
        g.add_option(
            "-i",
            "--interactive",
            dest="interactive",
            action="store_true",
            help="use interactive staging",
        )

    def Execute(self, opt, args):
        if opt.interactive:
            self._Interactive(opt, args)
        else:
            self.Usage()

    def _Interactive(self, opt, args):
        all_projects = [
            p
            for p in self.GetProjects(
                args, all_manifests=not opt.this_manifest_only
            )
            if p.IsDirty()
        ]
        if not all_projects:
            logger.error("no projects have uncommitted modifications")
            return

        out = _ProjectList(self.manifest.manifestProject.config)
        while True:
            out.header("        %s", "project")
            out.nl()

            for i in range(len(all_projects)):
                project = all_projects[i]
                out.write(
                    "%3d:    %s",
                    i + 1,
                    project.RelPath(local=opt.this_manifest_only) + "/",
                )
                out.nl()
            out.nl()

            out.write("%3d: (", 0)
            out.prompt("q")
            out.write("uit)")
            out.nl()

            out.prompt("project> ")
            out.flush()
            try:
                a = sys.stdin.readline()
            except KeyboardInterrupt:
                out.nl()
                break
            if a == "":
                out.nl()
                break

            a = a.strip()
            if a.lower() in ("q", "quit", "exit"):
                break
            if not a:
                continue

            try:
                a_index = int(a)
            except ValueError:
                a_index = None

            if a_index is not None:
                if a_index == 0:
                    break
                if 0 < a_index and a_index <= len(all_projects):
                    _AddI(all_projects[a_index - 1])
                    continue

            projects = [
                p
                for p in all_projects
                if a in [p.name, p.RelPath(local=opt.this_manifest_only)]
            ]
            if len(projects) == 1:
                _AddI(projects[0])
                continue
        print("Bye.")


def _AddI(project):
    p = GitCommand(project, ["add", "--interactive"], bare=False)
    p.Wait()
