# Copyright (C) 2011 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 os

from command import Command, MirrorSafeCommand


class List(Command, MirrorSafeCommand):
    COMMON = True
    helpSummary = "List projects and their associated directories"
    helpUsage = """
%prog [-f] [<project>...]
%prog [-f] -r str1 [str2]...
"""
    helpDescription = """
List all projects; pass '.' to list the project for the cwd.

By default, only projects that currently exist in the checkout are shown.  If
you want to list all projects (using the specified filter settings), use the
--all option.  If you want to show all projects regardless of the manifest
groups, then also pass --groups all.

This is similar to running: repo forall -c 'echo "$REPO_PATH : $REPO_PROJECT"'.
"""

    def _Options(self, p):
        p.add_option(
            "-r",
            "--regex",
            dest="regex",
            action="store_true",
            help="filter the project list based on regex or wildcard matching "
            "of strings",
        )
        p.add_option(
            "-g",
            "--groups",
            dest="groups",
            help="filter the project list based on the groups the project is "
            "in",
        )
        p.add_option(
            "-a",
            "--all",
            action="store_true",
            help="show projects regardless of checkout state",
        )
        p.add_option(
            "-n",
            "--name-only",
            dest="name_only",
            action="store_true",
            help="display only the name of the repository",
        )
        p.add_option(
            "-p",
            "--path-only",
            dest="path_only",
            action="store_true",
            help="display only the path of the repository",
        )
        p.add_option(
            "-f",
            "--fullpath",
            dest="fullpath",
            action="store_true",
            help="display the full work tree path instead of the relative path",
        )
        p.add_option(
            "--relative-to",
            metavar="PATH",
            help="display paths relative to this one (default: top of repo "
            "client checkout)",
        )

    def ValidateOptions(self, opt, args):
        if opt.fullpath and opt.name_only:
            self.OptionParser.error("cannot combine -f and -n")

        # Resolve any symlinks so the output is stable.
        if opt.relative_to:
            opt.relative_to = os.path.realpath(opt.relative_to)

    def Execute(self, opt, args):
        """List all projects and the associated directories.

        This may be possible to do with 'repo forall', but repo newbies have
        trouble figuring that out.  The idea here is that it should be more
        discoverable.

        Args:
            opt: The options.
            args: Positional args.  Can be a list of projects to list, or empty.
        """
        if not opt.regex:
            projects = self.GetProjects(
                args,
                groups=opt.groups,
                missing_ok=opt.all,
                all_manifests=not opt.this_manifest_only,
            )
        else:
            projects = self.FindProjects(
                args, all_manifests=not opt.this_manifest_only
            )

        def _getpath(x):
            if opt.fullpath:
                return x.worktree
            if opt.relative_to:
                return os.path.relpath(x.worktree, opt.relative_to)
            return x.RelPath(local=opt.this_manifest_only)

        lines = []
        for project in projects:
            if opt.name_only and not opt.path_only:
                lines.append("%s" % (project.name))
            elif opt.path_only and not opt.name_only:
                lines.append("%s" % (_getpath(project)))
            else:
                lines.append("%s : %s" % (_getpath(project), project.name))

        if lines:
            lines.sort()
            print("\n".join(lines))
