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

# Initiate a test case directory.
# This script copy a template which contains Android.mk, __init__.py files,
# AndroidTest.xml and a test case python file into a given relative directory
# under testcases/ using the given test name.

import os
import sys
import datetime
import re
import shutil
import argparse

VTS_PATH = 'test/vts'
VTS_TEST_CASE_PATH = os.path.join(VTS_PATH, 'testcases')
PYTHON_INIT_FILE_NAME = '__init__.py'
ANDROID_MK_FILE_NAME = 'Android.mk'
ANDROID_TEST_XML_FILE_NAME = 'AndroidTest.xml'


class TestCaseCreator(object):
    '''Init a test case directory with helloworld test case.

    Attributes:
        test_name: string, test case name in UpperCamel
        build_top: string, equal to environment variable ANDROID_BUILD_TOP
        test_dir: string, test case absolute directory
        test_name: string, test case name in UpperCamel
        test_plan: string, the plan that the test belongs to
        test_type: test type, such as HidlHalTest, HostDrivenTest, etc
        current_year: current year
        vts_test_case_dir: absolute dir of vts testcases directory
    '''

    def __init__(self, test_name, test_plan, test_dir_under_testcases,
                 test_type):
        '''Initialize class attributes.

        Args:
            test_name: string, test case name in UpperCamel
            test_plan: string, the plan that the test belongs to
            test_dir_under_testcases: string, test case relative directory under
                                      test/vts/testcases.
        '''
        if not test_dir_under_testcases:
            print 'Error: Empty test directory entered. Exiting'
            sys.exit(3)
        test_dir_under_testcases = os.path.normpath(
            test_dir_under_testcases.strip())

        if not self.IsUpperCamel(test_name):
            print 'Error: Test name not in UpperCamel case. Exiting'
            sys.exit(4)
        self.test_name = test_name

        if not test_plan:
            self.test_plan = 'vts-misc'
        else:
            self.test_plan = test_plan

        if not test_type:
            self.test_type = 'HidlHalTest'
        else:
            self.test_type = test_type

        self.build_top = os.getenv('ANDROID_BUILD_TOP')
        if not self.build_top:
            print('Error: Missing ANDROID_BUILD_TOP env variable. Please run '
                  '\'. build/envsetup.sh; lunch <build target>\' Exiting...')
            sys.exit(1)

        self.vts_test_case_dir = os.path.abspath(
            os.path.join(self.build_top, VTS_TEST_CASE_PATH))

        self.test_dir = os.path.abspath(
            os.path.join(self.vts_test_case_dir, test_dir_under_testcases))

        self.current_year = datetime.datetime.now().year

    def InitTestCaseDir(self):
        '''Start init test case directory'''
        if os.path.exists(self.test_dir):
            print 'Error: Test directory already exists. Exiting...'
            sys.exit(2)
        try:
            os.makedirs(self.test_dir)
        except:
            print('Error: Failed to create test directory at %s. '
                  'Exiting...' % self.test_dir)
            sys.exit(2)

        self.CreatePythonInitFile()
        self.CreateAndroidMk()
        self.CreateAndroidTestXml()
        self.CreateTestCasePy()

    def UpperCamelToLowerUnderScore(self, name):
        '''Convert UpperCamel name to lower_under_score name.

        Args:
            name: string in UpperCamel.

        Returns:
            a lower_under_score version of the given name
        '''
        return re.sub('(?!^)([A-Z]+)', r'_\1', name).lower()

    def IsUpperCamel(self, name):
        '''Check whether a given name is UpperCamel case.

        Args:
            name: string.

        Returns:
            True if name is in UpperCamel case, False otherwise
        '''
        regex = re.compile('((?:[A-Z][a-z]+)[0-9]*)+')
        match = regex.match(name)
        return match and (match.end() - match.start() == len(name))

    def CreatePythonInitFile(self):
        '''Populate test case directory and parent directories with __init__.py.
        '''
        if not self.test_dir.startswith(self.vts_test_case_dir):
            print 'Error: Test case directory is not under VTS test case directory.'
            sys.exit(4)

        path = self.test_dir
        while not path == self.vts_test_case_dir:
            target = os.path.join(path, PYTHON_INIT_FILE_NAME)
            if not os.path.exists(target):
                print 'Creating %s' % target
                with open(target, 'w') as f:
                    pass
            path = os.path.dirname(path)

    def CreateAndroidMk(self):
        '''Populate test case directory and parent directories with Android.mk
        '''
        vts_dir = os.path.join(self.build_top, VTS_PATH)

        target = os.path.join(self.test_dir, ANDROID_MK_FILE_NAME)
        with open(target, 'w') as f:
            print 'Creating %s' % target
            f.write(LICENSE_STATEMENT_POUND.format(year=self.current_year))
            f.write('\n')
            f.write(
                ANDROID_MK_TEMPLATE.format(
                    test_name=self.test_name,
                    config_src_dir=self.test_dir[len(vts_dir) + 1:]))

        path = self.test_dir
        while not path == vts_dir:
            target = os.path.join(path, ANDROID_MK_FILE_NAME)
            if not os.path.exists(target):
                print 'Creating %s' % target
                with open(target, 'w') as f:
                    f.write(
                        LICENSE_STATEMENT_POUND.format(year=self.current_year))
                    f.write(ANDROID_MK_CALL_SUB)
            path = os.path.dirname(path)

    def CreateAndroidTestXml(self):
        '''Create AndroidTest.xml'''
        target = os.path.join(self.test_dir, ANDROID_TEST_XML_FILE_NAME)
        with open(target, 'w') as f:
            print 'Creating %s' % target
            f.write(XML_HEADER)
            f.write(LICENSE_STATEMENT_XML.format(year=self.current_year))
            f.write(
                ANDROID_TEST_XML_TEMPLATE.format(
                    test_name=self.test_name,
                    test_plan=self.test_plan,
                    test_type=self.test_type,
                    test_path_under_vts=self.test_dir[
                        len(os.path.join(self.build_top, VTS_PATH)) + 1:],
                    test_case_file_without_extension=self.test_name))

    def CreateTestCasePy(self):
        '''Create <test_case_name>.py'''
        target = os.path.join(self.test_dir, '%s.py' % self.test_name)
        with open(target, 'w') as f:
            print 'Creating %s' % target
            f.write(PY_HEADER)
            f.write(LICENSE_STATEMENT_POUND.format(year=self.current_year))
            f.write('\n')
            f.write(TEST_CASE_PY_TEMPLATE.format(test_name=self.test_name))


def main():
    parser = argparse.ArgumentParser(description='Initiate a test case.')
    parser.add_argument(
        '--name',
        dest='test_name',
        required=True,
        help='Test case name in UpperCamel. Example: VtsKernelLtp')
    parser.add_argument(
        '--plan',
        dest='test_plan',
        required=False,
        help='The plan that the test belongs to. Example: vts-kernel')
    parser.add_argument(
        '--dir',
        dest='test_dir',
        required=True,
        help='Test case relative directory under test/vts/testcses.')
    parser.add_argument(
        '--type',
        dest='test_type',
        required=False,
        help='Test type, such as HidlHalTest, HostDrivenTest, etc.')

    args = parser.parse_args()
    test_case_creater = TestCaseCreator(args.test_name, args.test_plan,
                                        args.test_dir, args.test_type)
    test_case_creater.InitTestCaseDir()


LICENSE_STATEMENT_POUND = '''#
# Copyright (C) {year} 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.
#
'''

LICENSE_STATEMENT_XML = '''<!-- Copyright (C) {year} 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.
-->
'''

ANDROID_MK_TEMPLATE = '''LOCAL_PATH := $(call my-dir)

include $(call all-subdir-makefiles)

include $(CLEAR_VARS)

LOCAL_MODULE := {test_name}
include test/vts/tools/build/Android.host_config.mk
'''

ANDROID_MK_CALL_SUB = '''LOCAL_PATH := $(call my-dir)

include $(call all-subdir-makefiles)
'''

XML_HEADER = '''<?xml version="1.0" encoding="utf-8"?>
'''

ANDROID_TEST_XML_TEMPLATE = '''<configuration description="Config for VTS {test_name} test cases">
    <option name="config-descriptor:metadata" key="plan" value="{test_plan}" />
    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.VtsFilePusher">
        <option name="push-group" value="{test_type}.push" />
    </target_preparer>
    <test class="com.android.tradefed.testtype.VtsMultiDeviceTest">
        <option name="test-module-name" value="{test_name}" />
        <option name="test-case-path" value="vts/{test_path_under_vts}/{test_case_file_without_extension}" />
    </test>
</configuration>
'''

PY_HEADER = '''#!/usr/bin/env python
'''

TEST_CASE_PY_TEMPLATE = '''import logging

from vts.runners.host import asserts
from vts.runners.host import base_test
from vts.runners.host import const
from vts.runners.host import test_runner



class {test_name}(base_test.BaseTestClass):
    """Two hello world test cases which use the shell driver."""

    def setUpClass(self):
        self.dut = self.android_devices[0]
        self.shell = self.dut.shell

    def testEcho1(self):
        """A simple testcase which sends a command."""
        results = self.shell.Execute("echo hello_world")  # runs a shell command.
        logging.info(str(results[const.STDOUT]))  # prints the stdout
        asserts.assertEqual(results[const.STDOUT][0].strip(), "hello_world")  # checks the stdout
        asserts.assertEqual(results[const.EXIT_CODE][0], 0)  # checks the exit code

    def testEcho2(self):
        """A simple testcase which sends two commands."""
        results = self.shell.Execute(["echo hello", "echo world"])
        logging.info(str(results[const.STDOUT]))
        asserts.assertEqual(len(results[const.STDOUT]), 2)  # check the number of processed commands
        asserts.assertEqual(results[const.STDOUT][0].strip(), "hello")
        asserts.assertEqual(results[const.STDOUT][1].strip(), "world")
        asserts.assertEqual(results[const.EXIT_CODE][0], 0)
        asserts.assertEqual(results[const.EXIT_CODE][1], 0)


if __name__ == "__main__":
    test_runner.main()
'''

if __name__ == '__main__':
    main()
