#
# 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 optparse
import sys

import manifest_loader

from error import NoSuchProjectError

class Command(object):
  """Base class for any command line action in repo.
  """

  common = False
  _optparse = None

  def WantPager(self, opt):
    return False

  @property
  def OptionParser(self):
    if self._optparse is None:
      try:
        me = 'repo %s' % self.NAME
        usage = self.helpUsage.strip().replace('%prog', me)
      except AttributeError:
        usage = 'repo %s' % self.NAME
      self._optparse = optparse.OptionParser(usage = usage)
      self._Options(self._optparse)
    return self._optparse

  def _Options(self, p):
    """Initialize the option parser.
    """

  def Usage(self):
    """Display usage and terminate.
    """
    self.OptionParser.print_usage()
    sys.exit(1)

  def Execute(self, opt, args):
    """Perform the action, after option parsing is complete.
    """
    raise NotImplementedError
 
  @property
  def manifest(self):
    return self.GetManifest()

  def GetManifest(self, reparse=False, type=None):
    return manifest_loader.GetManifest(self.repodir,
                                       reparse=reparse,
                                       type=type)

  def GetProjects(self, args, missing_ok=False):
    """A list of projects that match the arguments.
    """
    all = self.manifest.projects

    mp = self.manifest.manifestProject
    if mp.relpath == '.':
      all = dict(all)
      all[mp.name] = mp

    result = []

    if not args:
      for project in all.values():
        if missing_ok or project.Exists:
          result.append(project)
    else:
      by_path = None

      for arg in args:
        project = all.get(arg)

        if not project:
          path = os.path.abspath(arg)

          if not by_path:
            by_path = dict()
            for p in all.values():
              by_path[p.worktree] = p

          try:
            project = by_path[path]
          except KeyError:
            while path \
              and path != '/' \
              and path != self.manifest.topdir:
              try:
                project = by_path[path]
                break
              except KeyError:
                path = os.path.dirname(path)

        if not project:
          raise NoSuchProjectError(arg)
        if not missing_ok and not project.Exists:
          raise NoSuchProjectError(arg)

        result.append(project)

    def _getpath(x):
      return x.relpath
    result.sort(key=_getpath)
    return result

class InteractiveCommand(Command):
  """Command which requires user interaction on the tty and
     must not run within a pager, even if the user asks to.
  """
  def WantPager(self, opt):
    return False

class PagedCommand(Command):
  """Command which defaults to output in a pager, as its
     display tends to be larger than one screen full.
  """
  def WantPager(self, opt):
    return True

class MirrorSafeCommand(object):
  """Command permits itself to run within a mirror,
     and does not require a working directory.
  """
