# 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",
            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()
