#!/usr/bin/python

# Copyright (C) 2009 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.

"""Module for generating CTS test descriptions and test plans."""

import glob
import os
import re
import subprocess
import sys
import xml.dom.minidom as dom
from cts import tools


def GetSubDirectories(root):
  """Return all directories under the given root directory."""
  return [x for x in os.listdir(root) if os.path.isdir(os.path.join(root, x))]


def GetMakeFileVars(makefile_path):
  """Extracts variable definitions from the given make file.

  Args:
    makefile_path: Path to the make file.

  Returns:
    A dictionary mapping variable names to their assigned value.
  """
  result = {}
  pattern = re.compile(r'^\s*([^:#=\s]+)\s*:=\s*(.*?[^\\])$', re.MULTILINE + re.DOTALL)
  stream = open(makefile_path, 'r')
  content = stream.read()
  for match in pattern.finditer(content):
    result[match.group(1)] = match.group(2)
  stream.close()
  return result


class CtsBuilder(object):
  """Main class for generating test descriptions and test plans."""

  def __init__(self, argv):
    """Initialize the CtsBuilder from command line arguments."""
    if not len(argv) == 6:
      print 'Usage: %s <testRoot> <ctsOutputDir> <tempDir> <androidRootDir> <docletPath>' % argv[0]
      print ''
      print 'testRoot:       Directory under which to search for CTS tests.'
      print 'ctsOutputDir:   Directory in which the CTS repository should be created.'
      print 'tempDir:        Directory to use for storing temporary files.'
      print 'androidRootDir: Root directory of the Android source tree.'
      print 'docletPath:     Class path where the DescriptionGenerator doclet can be found.'
      sys.exit(1)
    self.test_root = sys.argv[1]
    self.out_dir = sys.argv[2]
    self.temp_dir = sys.argv[3]
    self.android_root = sys.argv[4]
    self.doclet_path = sys.argv[5]

    self.test_repository = os.path.join(self.out_dir, 'repository/testcases')
    self.plan_repository = os.path.join(self.out_dir, 'repository/plans')

  def __LogGenerateDescription(self, name):
    print 'Generating test description for package %s' % name

  def RunDescriptionGeneratorDoclet(self, source_root, output_file):
    """Generate a test package description by running the DescriptionGenerator doclet.

    Args:
      source_root: Directory under which tests should be searched.
      output_file: Name of the file where the description gets written.

    Returns:
      The exit code of the DescriptionGenerator doclet run.
    """
    # Make sure sourceRoot is relative to  self.android_root
    source_root = self.RelPath(source_root, self.android_root)

    # To determine whether a class is a JUnit test, the Doclet needs to have all intermediate
    # subclasses of TestCase as well as the JUnit framework itself on the source path.
    # Annotation classes are also required, since test annotations go into the description.
    source_path = [
        'frameworks/base/core/java',            # android test classes
        'frameworks/base/test-runner/src',      # test runner
        'dalvik/libcore/junit/src/main/java',   # junit classes
        'development/tools/hosttestlib/src',    # hosttestlib TestCase extensions
        'dalvik/libcore/dalvik/src/main/java',  # test annotations
        'cts/tests/src',                        # cts test stubs
        source_root                             # the source for this package
    ]
    source_path = [os.path.join(self.android_root, x) for x in source_path]
    cmd = ('javadoc -o %s -J-Xmx512m -quiet -doclet DescriptionGenerator -docletpath %s'
           ' -sourcepath %s ') % (output_file, self.doclet_path, ':'.join(source_path))
    sources = []

    def AddFile(sources, folder, names):
      """Find *.java."""
      sources.extend([os.path.join(folder, name) for name in names if name.endswith('.java')])

    os.path.walk(os.path.join(self.android_root, source_root), AddFile, sources)
    cmd += ' '.join(sources)
    proc = subprocess.Popen(cmd, shell=True, stderr=subprocess.STDOUT, stdout=subprocess.PIPE)
    # read and discard any output
    proc.communicate()
    # wait for process to terminate and return exit value
    return proc.wait()

  def GenerateSignatureCheckDescription(self):
    """Generate the test description for the signature check."""
    self.__LogGenerateDescription('android.tests.sigtest')
    package = tools.TestPackage('SignatureTest', 'android.tests.sigtest')
    package.AddAttribute('signatureCheck', 'true')
    package.AddAttribute('runner', '.InstrumentationRunner')
    package.AddTest('android.tests.sigtest.SignatureTest.signatureTest')
    description = open(os.path.join(self.test_repository, 'SignatureTest.xml'), 'w')
    package.WriteDescription(description)
    description.close()

  def GenerateReferenceAppDescription(self):
    """Generate the test description for the reference app tests."""
    self.__LogGenerateDescription('android.apidemos.cts')
    package = tools.TestPackage('ApiDemosReferenceTest', 'android.apidemos.cts')
    package.AddAttribute('packageToTest', 'com.example.android.apis')
    package.AddAttribute('apkToTestName', 'ApiDemos')
    package.AddAttribute('runner', 'android.test.InstrumentationTestRunner')
    package.AddAttribute('referenceAppTest', 'true')
    package.AddTest('android.apidemos.cts.ApiDemosTest.testNumberOfItemsInListView')
    description = open(os.path.join(self.test_repository, 'ApiDemosReferenceTest.xml'), 'w')
    package.WriteDescription(description)
    description.close()

  def GenerateAppSecurityDescription(self):
    """Generate the test description for the application security tests."""
    test_root = 'cts/tests/appsecurity-tests'
    makefile_name = os.path.join(test_root, 'Android.mk')
    makefile_vars = GetMakeFileVars(makefile_name)
    name = makefile_vars['LOCAL_MODULE']
    package_name = 'android.tests.appsecurity'
    self.__LogGenerateDescription(package_name)
    temp_desc = os.path.join(self.temp_dir, 'description.xml')
    self.RunDescriptionGeneratorDoclet(os.path.join(test_root, 'src'), temp_desc)
    doc = dom.parse(temp_desc)
    test_description = doc.getElementsByTagName('TestPackage')[0]
    test_description.setAttribute('name', package_name)
    test_description.setAttribute('appPackageName', package_name)
    test_description.setAttribute('hostSideOnly', 'true')
    test_description.setAttribute('jarPath', name + '.jar')
    description = open(os.path.join(self.test_repository, package_name + '.xml'), 'w')
    doc.writexml(description, addindent='    ', encoding='UTF-8')
    description.close()

  @staticmethod
  def RelPath(path, start=os.getcwd()):
    """Get a relative version of a path.

    This is equivalent to os.path.relpath, which is only available since Python 2.6.

    Args:
      path: The path to transform.
      start: The base path. Defaults to the current working directory.

    Returns:
      A transformed path that is relative to start.
    """
    path_dirs = os.path.abspath(path).split(os.path.sep)
    start_dirs = os.path.abspath(start).split(os.path.sep)

    num_common = len(os.path.commonprefix([start_dirs, path_dirs]))

    result_dirs = ['..'] * (len(start_dirs) - num_common) + path_dirs[num_common:]
    if result_dirs:
      return os.path.join(*result_dirs)
    return start

  def GenerateTestDescriptions(self):
    """Generate test descriptions for all packages."""
    # individually generate descriptions not following conventions
    self.GenerateSignatureCheckDescription()
    self.GenerateReferenceAppDescription()
    self.GenerateAppSecurityDescription()

    # generate test descriptions for android tests
    android_packages = GetSubDirectories(self.test_root)
    for package in android_packages:
      app_package_name = 'android.' + package
      package_root = os.path.join(self.test_root, package)

      makefile_name = os.path.join(package_root, 'Android.mk')
      if not os.path.exists(makefile_name):
        print 'Skipping directory "%s" due to missing Android.mk' % package_root
        continue
      makefile_vars = GetMakeFileVars(makefile_name)

      manifest_name = os.path.join(package_root, 'AndroidManifest.xml')
      if not os.path.exists(manifest_name):
        print 'Skipping directory "%s" due to missing AndroidManifest.xml' % package_root
        continue
      manifest = tools.XmlFile(manifest_name)

      self.__LogGenerateDescription(app_package_name)

      # Run the description generator doclet to get the test package structure
      # TODO: The Doclet does not currently add all required attributes. Instead of rewriting
      # the document below, additional attributes should be passed to the Doclet as arguments.
      temp_desc = os.path.join(self.temp_dir, 'description.xml')
      self.RunDescriptionGeneratorDoclet(package_root, temp_desc)

      # obtain missing attribute values from the makefile and manifest
      package_name = makefile_vars['LOCAL_PACKAGE_NAME']
      runner = manifest.GetAndroidAttr('instrumentation', 'name')
      target_package = manifest.GetAndroidAttr('instrumentation', 'targetPackage')
      target_binary_name = makefile_vars.get('LOCAL_INSTRUMENTATION_FOR')

      # add them to the document
      doc = dom.parse(temp_desc)
      test_description = doc.getElementsByTagName('TestPackage')[0]
      test_description.setAttribute('name', package_name)
      test_description.setAttribute('runner', runner)
      test_package = manifest.GetAttr('manifest', 'package')
      test_description.setAttribute('appNameSpace', test_package)
      test_description.setAttribute('appPackageName', app_package_name)
      if not test_package == target_package:
        test_description.setAttribute('targetNameSpace', target_package)
        test_description.setAttribute('targetBinaryName', target_binary_name)
      description = open(os.path.join(self.test_repository, package_name + '.xml'), 'w')
      doc.writexml(description, addindent='    ', encoding='UTF-8')
      description.close()

  def __WritePlan(self, plan, plan_name):
    print 'Generating test plan %s' % plan_name
    plan.Write(os.path.join(self.plan_repository, plan_name + '.xml'))

  def GenerateTestPlans(self):
    """Generate default test plans."""
    # TODO: Instead of hard-coding the plans here, use a configuration file,
    # such as test_defs.xml
    packages = []
    descriptions = sorted(glob.glob(os.path.join(self.test_repository, '*.xml')))
    for description in descriptions:
      doc = tools.XmlFile(description)
      packages.append(doc.GetAttr('TestPackage', 'appPackageName'))

    plan = tools.TestPlan(packages)
    plan.Exclude('android\.performance.*')
    self.__WritePlan(plan, 'CTS')
    plan.Exclude(r'android\.tests\.sigtest')
    plan.Exclude(r'android\.core.*')
    self.__WritePlan(plan, 'Android')

    plan = tools.TestPlan(packages)
    plan.Include(r'android\.core\.tests.*')
    self.__WritePlan(plan, 'Java')

    plan = tools.TestPlan(packages)
    plan.Include(r'android\.core\.vm-tests')
    self.__WritePlan(plan, 'VM')

    plan = tools.TestPlan(packages)
    plan.Include(r'android\.tests\.sigtest')
    self.__WritePlan(plan, 'Signature')

    plan = tools.TestPlan(packages)
    plan.Include(r'android\.apidemos\.cts')
    self.__WritePlan(plan, 'RefApp')

    plan = tools.TestPlan(packages)
    plan.Include(r'android\.performance.*')
    self.__WritePlan(plan, 'Performance')

    plan = tools.TestPlan(packages)
    plan.Include(r'android\.tests\.appsecurity')
    self.__WritePlan(plan, 'AppSecurity')


if __name__ == '__main__':
  builder = CtsBuilder(sys.argv)
  builder.GenerateTestDescriptions()
  builder.GenerateTestPlans()
