#!/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',
    '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 FLAGS.force and 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)
