#!/usr/bin/env python
#
# Copyright 2007 Google Inc.
#
# 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.

"""Copy the sources for google-api-python-client into an App Engine project.

Copies the sources of the google-api-python-client
library into a Google App Engine project. This is necessary so that the
source can be uploaded when the application is deployed.

  $ enable-app-engine-project [flags] directory

"""

__author__ = 'jcgregorio@google.com (Joe Gregorio)'

import gflags
import logging
import sys
import os
import pkg_resources

from distutils.dir_util import copy_tree
from distutils.file_util import copy_file
from distutils.errors import DistutilsFileError

FLAGS = gflags.FLAGS
SOURCES = [
    'gflags',
    'gflags_validators',
    'httplib2',
    'oauth2client',
    'oauth2',
    'apiclient',
    'uritemplate',
    ]

gflags.DEFINE_enum('logging_level', 'ERROR',
    ['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL'],
    'Set the level of logging detail.')

gflags.DEFINE_boolean('force', 'False',
    'Forcibly copy over client library files.')

gflags.DEFINE_boolean('dry_run', 'False', 'Don\'t actually do anything.')

def find_source(module):
  """Find the absolute path for the source of a module.

  Args:
    module: str, Name of the module.
  Returns:
    A tuple of (isdir, location), a boolean that's True if
    the source is a directory, False is it's a file,
    and the absolute path of the source.
  """
  isdir = False
  location = ''
  m = __import__(module)
  logging.debug('Absolute path for module %s: %s' % (module, m.__file__))
  basename = os.path.basename(m.__file__)
  if basename.startswith('__init__.'):
    isdir = True
    location = os.path.dirname(
        pkg_resources.resource_filename(module, '__init__.py'))
  else:
    if os.path.isfile(m.__file__):
      location = m.__file__.rsplit('.', 1)[0] + '.py'
    else:
      # The file is an egg, extract to a temporary location
      location = pkg_resources.resource_filename(module, module + '.py')

  return (isdir, location)

def main(argv):
  # Let the gflags module process the command-line arguments
  try:
    argv = FLAGS(argv)
  except gflags.FlagsError, e:
    print '%s\nUsage: %s ARGS\n%s' % (e, argv[0], FLAGS)
    sys.exit(1)

  if len(argv) == 1:
    print 'Usage: %s ARGS\n%s' % (argv[0], FLAGS)
    sys.exit(1)

  # Set the logging according to the command-line flag
  logging.getLogger().setLevel(getattr(logging, FLAGS.logging_level))

  logging.info('Setting up the directories: %s' % argv[1:])
  for dir in argv[1:]:
    # Check if the supplied directory is an App Engine project by looking
    # for an app.yaml
    if not os.path.isfile(os.path.join(dir, 'app.yaml')):
      sys.exit('The given directory is not a Google App Engine project: %s' %
               dir)

    # Build up the set of file or directory copying actions we need to do
    action = [] # (src, dst, isdir)
    for source in SOURCES:
      isdir, source_location = find_source(source)
      if isdir:
        target = source
      else:
        target = source + ".py"
      full_target = os.path.join(dir, target)
      if not FLAGS.force and os.path.exists(full_target):
        noun = isdir and 'Directory' or 'File'
        sys.exit("%s already exists in project: %s" % (noun, target))
      action.append((source_location, full_target, isdir))

    # Now perform all the copying actions we collected
    try:
      for src, dst, isdir in action:
        if isdir:
          results = copy_tree(src, dst, FLAGS.dry_run)
          for filename in results:
            print 'Copied: %s' % filename
        else:
          filename, copied = copy_file(src, dst, FLAGS.dry_run)
          print 'Copied: %s Successfully: %s' % (filename, copied)
    except DistutilsFileError, e:
      sys.exit(str(e))

if __name__ == '__main__':
  main(sys.argv)
