# 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 os
import platform
import re
import sys
import urllib.parse

from color import Coloring
from command import InteractiveCommand, MirrorSafeCommand
from error import ManifestParseError
from project import SyncBuffer
from git_config import GitConfig
from git_command import git_require, MIN_GIT_VERSION_SOFT, MIN_GIT_VERSION_HARD
from wrapper import Wrapper


class Init(InteractiveCommand, MirrorSafeCommand):
  COMMON = True
  MULTI_MANIFEST_SUPPORT = True
  helpSummary = "Initialize a repo client checkout in the current directory"
  helpUsage = """
%prog [options] [manifest url]
"""
  helpDescription = """
The '%prog' command is run once to install and initialize repo.
The latest repo source code and manifest collection is downloaded
from the server and is installed in the .repo/ directory in the
current working directory.

When creating a new checkout, the manifest URL is the only required setting.
It may be specified using the --manifest-url option, or as the first optional
argument.

The optional -b argument can be used to select the manifest branch
to checkout and use.  If no branch is specified, the remote's default
branch is used.  This is equivalent to using -b HEAD.

The optional -m argument can be used to specify an alternate manifest
to be used. If no manifest is specified, the manifest default.xml
will be used.

If the --standalone-manifest argument is set, the manifest will be downloaded
directly from the specified --manifest-url as a static file (rather than
setting up a manifest git checkout). With --standalone-manifest, the manifest
will be fully static and will not be re-downloaded during subsesquent
`repo init` and `repo sync` calls.

The --reference option can be used to point to a directory that
has the content of a --mirror sync. This will make the working
directory use as much data as possible from the local reference
directory when fetching from the server. This will make the sync
go a lot faster by reducing data traffic on the network.

The --dissociate option can be used to borrow the objects from
the directory specified with the --reference option only to reduce
network transfer, and stop borrowing from them after a first clone
is made by making necessary local copies of borrowed objects.

The --no-clone-bundle option disables any attempt to use
$URL/clone.bundle to bootstrap a new Git repository from a
resumeable bundle file on a content delivery network. This
may be necessary if there are problems with the local Python
HTTP client or proxy configuration, but the Git binary works.

# Switching Manifest Branches

To switch to another manifest branch, `repo init -b otherbranch`
may be used in an existing client.  However, as this only updates the
manifest, a subsequent `repo sync` (or `repo sync -d`) is necessary
to update the working directory files.
"""

  def _CommonOptions(self, p):
    """Disable due to re-use of Wrapper()."""

  def _Options(self, p, gitc_init=False):
    Wrapper().InitParser(p, gitc_init=gitc_init)
    m = p.add_option_group('Multi-manifest')
    m.add_option('--outer-manifest', action='store_true', default=True,
                 help='operate starting at the outermost manifest')
    m.add_option('--no-outer-manifest', dest='outer_manifest',
                 action='store_false', help='do not operate on outer manifests')
    m.add_option('--this-manifest-only', action='store_true', default=None,
                 help='only operate on this (sub)manifest')
    m.add_option('--no-this-manifest-only', '--all-manifests',
                 dest='this_manifest_only', action='store_false',
                 help='operate on this manifest and its submanifests')

  def _RegisteredEnvironmentOptions(self):
    return {'REPO_MANIFEST_URL': 'manifest_url',
            'REPO_MIRROR_LOCATION': 'reference'}

  def _SyncManifest(self, opt):
    """Call manifestProject.Sync with arguments from opt.

    Args:
      opt: options from optparse.
    """
    if not self.manifest.manifestProject.Sync(
        manifest_url=opt.manifest_url,
        manifest_branch=opt.manifest_branch,
        standalone_manifest=opt.standalone_manifest,
        groups=opt.groups,
        platform=opt.platform,
        mirror=opt.mirror,
        dissociate=opt.dissociate,
        reference=opt.reference,
        worktree=opt.worktree,
        submodules=opt.submodules,
        archive=opt.archive,
        partial_clone=opt.partial_clone,
        clone_filter=opt.clone_filter,
        partial_clone_exclude=opt.partial_clone_exclude,
        clone_bundle=opt.clone_bundle,
        git_lfs=opt.git_lfs,
        use_superproject=opt.use_superproject,
        verbose=opt.verbose,
        current_branch_only=opt.current_branch_only,
        tags=opt.tags,
        depth=opt.depth,
        git_event_log=self.git_event_log,
        manifest_name=opt.manifest_name):
      sys.exit(1)

  def _Prompt(self, prompt, value):
    print('%-10s [%s]: ' % (prompt, value), end='')
    # TODO: When we require Python 3, use flush=True w/print above.
    sys.stdout.flush()
    a = sys.stdin.readline().strip()
    if a == '':
      return value
    return a

  def _ShouldConfigureUser(self, opt, existing_checkout):
    gc = self.client.globalConfig
    mp = self.manifest.manifestProject

    # If we don't have local settings, get from global.
    if not mp.config.Has('user.name') or not mp.config.Has('user.email'):
      if not gc.Has('user.name') or not gc.Has('user.email'):
        return True

      mp.config.SetString('user.name', gc.GetString('user.name'))
      mp.config.SetString('user.email', gc.GetString('user.email'))

    if not opt.quiet and not existing_checkout or opt.verbose:
      print()
      print('Your identity is: %s <%s>' % (mp.config.GetString('user.name'),
                                           mp.config.GetString('user.email')))
      print("If you want to change this, please re-run 'repo init' with --config-name")
    return False

  def _ConfigureUser(self, opt):
    mp = self.manifest.manifestProject

    while True:
      if not opt.quiet:
        print()
      name = self._Prompt('Your Name', mp.UserName)
      email = self._Prompt('Your Email', mp.UserEmail)

      if not opt.quiet:
        print()
      print('Your identity is: %s <%s>' % (name, email))
      print('is this correct [y/N]? ', end='')
      # TODO: When we require Python 3, use flush=True w/print above.
      sys.stdout.flush()
      a = sys.stdin.readline().strip().lower()
      if a in ('yes', 'y', 't', 'true'):
        break

    if name != mp.UserName:
      mp.config.SetString('user.name', name)
    if email != mp.UserEmail:
      mp.config.SetString('user.email', email)

  def _HasColorSet(self, gc):
    for n in ['ui', 'diff', 'status']:
      if gc.Has('color.%s' % n):
        return True
    return False

  def _ConfigureColor(self):
    gc = self.client.globalConfig
    if self._HasColorSet(gc):
      return

    class _Test(Coloring):
      def __init__(self):
        Coloring.__init__(self, gc, 'test color display')
        self._on = True
    out = _Test()

    print()
    print("Testing colorized output (for 'repo diff', 'repo status'):")

    for c in ['black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan']:
      out.write(' ')
      out.printer(fg=c)(' %-6s ', c)
    out.write(' ')
    out.printer(fg='white', bg='black')(' %s ' % 'white')
    out.nl()

    for c in ['bold', 'dim', 'ul', 'reverse']:
      out.write(' ')
      out.printer(fg='black', attr=c)(' %-6s ', c)
    out.nl()

    print('Enable color display in this user account (y/N)? ', end='')
    # TODO: When we require Python 3, use flush=True w/print above.
    sys.stdout.flush()
    a = sys.stdin.readline().strip().lower()
    if a in ('y', 'yes', 't', 'true', 'on'):
      gc.SetString('color.ui', 'auto')

  def _DisplayResult(self, opt):
    if self.manifest.IsMirror:
      init_type = 'mirror '
    else:
      init_type = ''

    if not opt.quiet:
      print()
      print('repo %shas been initialized in %s' %
            (init_type, self.manifest.topdir))

    current_dir = os.getcwd()
    if current_dir != self.manifest.topdir:
      print('If this is not the directory in which you want to initialize '
            'repo, please run:')
      print('   rm -r %s' % os.path.join(self.manifest.topdir, '.repo'))
      print('and try again.')

  def ValidateOptions(self, opt, args):
    if opt.reference:
      opt.reference = os.path.expanduser(opt.reference)

    # Check this here, else manifest will be tagged "not new" and init won't be
    # possible anymore without removing the .repo/manifests directory.
    if opt.mirror:
      if opt.archive:
        self.OptionParser.error('--mirror and --archive cannot be used '
                                'together.')
      if opt.use_superproject is not None:
        self.OptionParser.error('--mirror and --use-superproject cannot be '
                                'used together.')
    if opt.archive and opt.use_superproject is not None:
      self.OptionParser.error('--archive and --use-superproject cannot be used '
                              'together.')

    if opt.standalone_manifest and (opt.manifest_branch or
                                    opt.manifest_name != 'default.xml'):
      self.OptionParser.error('--manifest-branch and --manifest-name cannot'
                              ' be used with --standalone-manifest.')

    if args:
      if opt.manifest_url:
        self.OptionParser.error(
            '--manifest-url option and URL argument both specified: only use '
            'one to select the manifest URL.')

      opt.manifest_url = args.pop(0)

      if args:
        self.OptionParser.error('too many arguments to init')

  def Execute(self, opt, args):
    git_require(MIN_GIT_VERSION_HARD, fail=True)
    if not git_require(MIN_GIT_VERSION_SOFT):
      print('repo: warning: git-%s+ will soon be required; please upgrade your '
            'version of git to maintain support.'
            % ('.'.join(str(x) for x in MIN_GIT_VERSION_SOFT),),
            file=sys.stderr)

    rp = self.manifest.repoProject

    # Handle new --repo-url requests.
    if opt.repo_url:
      remote = rp.GetRemote('origin')
      remote.url = opt.repo_url
      remote.Save()

    # Handle new --repo-rev requests.
    if opt.repo_rev:
      wrapper = Wrapper()
      try:
        remote_ref, rev = wrapper.check_repo_rev(
            rp.gitdir, opt.repo_rev, repo_verify=opt.repo_verify, quiet=opt.quiet)
      except wrapper.CloneFailure:
        print('fatal: double check your --repo-rev setting.', file=sys.stderr)
        sys.exit(1)
      branch = rp.GetBranch('default')
      branch.merge = remote_ref
      rp.work_git.reset('--hard', rev)
      branch.Save()

    if opt.worktree:
      # Older versions of git supported worktree, but had dangerous gc bugs.
      git_require((2, 15, 0), fail=True, msg='git gc worktree corruption')

    # Provide a short notice that we're reinitializing an existing checkout.
    # Sometimes developers might not realize that they're in one, or that
    # repo doesn't do nested checkouts.
    existing_checkout = self.manifest.manifestProject.Exists
    if not opt.quiet and existing_checkout:
      print('repo: reusing existing repo client checkout in', self.manifest.topdir)

    self._SyncManifest(opt)

    if os.isatty(0) and os.isatty(1) and not self.manifest.IsMirror:
      if opt.config_name or self._ShouldConfigureUser(opt, existing_checkout):
        self._ConfigureUser(opt)
      self._ConfigureColor()

    self._DisplayResult(opt)
