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

"""Functional test for aidegen project files."""

from __future__ import absolute_import
from __future__ import print_function

import argparse
import functools
import itertools
import json
import logging
import os
import subprocess
import sys
import xml.etree.ElementTree
import xml.parsers.expat

from aidegen import aidegen_main
from aidegen import constant
from aidegen.lib import clion_project_file_gen
# pylint: disable=no-name-in-module
from aidegen.lib import common_util
from aidegen.lib import errors
from aidegen.lib import module_info_util
from aidegen.lib import project_config
from aidegen.lib import project_file_gen

from atest import module_info

_PRODUCT_DIR = '$PROJECT_DIR$'
_ROOT_DIR = os.path.join(common_util.get_android_root_dir(),
                         'tools/asuite/aidegen_functional_test')
_TEST_DATA_PATH = os.path.join(_ROOT_DIR, 'test_data')
_VERIFY_COMMANDS_JSON = os.path.join(_TEST_DATA_PATH, 'verify_commands.json')
_GOLDEN_SAMPLES_JSON = os.path.join(_TEST_DATA_PATH, 'golden_samples.json')
_VERIFY_BINARY_JSON = os.path.join(_TEST_DATA_PATH, 'verify_binary_upload.json')
_VERIFY_PRESUBMIT_JSON = os.path.join(_TEST_DATA_PATH, 'verify_presubmit.json')
_ANDROID_COMMON = 'android_common'
_LINUX_GLIBC_COMMON = 'linux_glibc_common'
_SRCS = 'srcs'
_JARS = 'jars'
_URL = 'url'
_TEST_ERROR = 'AIDEGen functional test error: {}-{} is different.'
_MSG_NOT_IN_PROJECT_FILE = ('{} is expected, but not found in the created '
                            'project file: {}')
_MSG_NOT_IN_SAMPLE_DATA = ('{} is unexpected, but found in the created project '
                           'file: {}')
_ALL_PASS = 'All tests passed!'
_GIT_COMMIT_ID_JSON = os.path.join(
    _TEST_DATA_PATH, 'baseline_code_commit_id.json')
_GIT = 'git'
_CHECKOUT = 'checkout'
_BRANCH = 'branch'
_COMMIT = 'commit'
_LOG = 'log'
_ALL = '--all'
_COMMIT_ID_NOT_EXIST_ERROR = ('Commit ID: {} does not exist in path: {}. '
                              'Please use "git log" command to check if it '
                              'exists. If it does not, try to update your '
                              'source files to the latest version or do not '
                              'use "repo init --depth=1" command.')
_GIT_LOG_ERROR = 'Command "git log -n 1" failed.'
_BE_REPLACED = '${config.X86_64GccRoot}'
_TO_REPLACE = 'prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.9'


def _parse_args(args):
    """Parse command line arguments.

    Args:
        args: A list of arguments.

    Returns:
        An argparse.Namespace object holding parsed args.
    """
    parser = argparse.ArgumentParser(
        description=__doc__,
        formatter_class=argparse.RawDescriptionHelpFormatter,
        usage='aidegen_functional_test [-c | -u | -b | -a] -v -r')
    group = parser.add_mutually_exclusive_group()
    parser.required = False
    parser.add_argument(
        'targets',
        type=str,
        nargs='*',
        default=[''],
        help='Android module name or path.e.g. frameworks/base')
    group.add_argument(
        '-c',
        '--create-sample',
        action='store_true',
        dest='create_sample',
        help=('Create aidegen project files and write data to sample json file '
              'for aidegen_functional_test to compare.'))
    parser.add_argument(
        '-v',
        '--verbose',
        action='store_true',
        help='Show DEBUG level logging.')
    parser.add_argument(
        '-r',
        '--remove_bp_json',
        action='store_true',
        help='Remove module_bp_java_deps.json for each use case test.')
    parser.add_argument(
        '-m',
        '--make_clean',
        action='store_true',
        help=('Make clean before testing to create a clean environment, the '
              'aidegen_functional_test can run only once if users command it.'))
    group.add_argument(
        '-u',
        '--use_cases',
        action='store_true',
        dest='use_cases_verified',
        help='Verify various use cases of executing aidegen.')
    group.add_argument(
        '-b',
        action='store_true',
        dest='binary_upload_verified',
        help=('Verify aidegen\'s use cases by executing different aidegen '
              'commands.'))
    group.add_argument(
        '-p',
        action='store_true',
        dest='binary_presubmit_verified',
        help=('Verify aidegen\'s tool in presubmit test by executing'
              'different aidegen commands.'))
    group.add_argument(
        '-a',
        '--test-all',
        action='store_true',
        dest='test_all_samples',
        help='Test all modules listed in module-info.json.')
    group.add_argument(
        '-n',
        '--compare-sample-native',
        action='store_true',
        dest='compare_sample_native',
        help=('Compare if sample native project file is the same as generated '
              'by the build system.'))
    return parser.parse_args(args)


def _import_project_file_xml_etree(filename):
    """Import iml project file and load its data into a dictionary.

    Args:
        filename: The input project file name.

    Returns:
        A dictionary contains dependent files' data of project file's contents.
        The samples are like:
        "srcs": [
            ...
            "file://$PROJECT_DIR$/frameworks/base/cmds/am/src",
            "file://$PROJECT_DIR$/frameworks/base/cmds/appwidget/src",
            ...
        ]
        "jars": [
            ...
            "jar://$PROJECT_DIR$/out/host/common/obj/**/classes-header.jar!/"
            ...
        ]

    Raises:
        EnvironmentError and xml parsing or format errors.
    """
    data = {}
    try:
        tree = xml.etree.ElementTree.parse(filename)
        data[_SRCS] = []
        root = tree.getroot()
        for element in root.iter('sourceFolder'):
            src = element.get(_URL).replace(common_util.get_android_root_dir(),
                                            _PRODUCT_DIR)
            data[_SRCS].append(src)
        data[_JARS] = []
        for element in root.iter('root'):
            jar = element.get(_URL).replace(common_util.get_android_root_dir(),
                                            _PRODUCT_DIR)
            data[_JARS].append(jar)
    except (EnvironmentError, ValueError, LookupError,
            xml.parsers.expat.ExpatError) as err:
        print("{0}: import error: {1}".format(os.path.basename(filename), err))
        raise
    return data


def _get_project_file_names(abs_path):
    """Get project file name and depenencies name by relative path.

    Args:
        abs_path: an absolute module's path.

    Returns:
        file_name: a string of the project file name.
        dep_name: a string of the merged project and dependencies file's name,
                  e.g., frameworks-dependencies.iml.
    """
    # pylint: disable=maybe-no-member
    code_name = project_file_gen.ProjectFileGenerator.get_unique_iml_name(
        abs_path)
    file_name = ''.join([code_name, '.iml'])
    dep_name = ''.join([constant.KEY_DEPENDENCIES, '.iml'])
    return file_name, dep_name


def _get_unique_module_name(rel_path, filename):
    """Get a unique project file name or dependencies name by relative path.

    Args:
        rel_path: a relative module's path to aosp root path.
        filename: the file name to be generated in module_in type file name.

    Returns:
        A string, the unique file name for the whole module-info.json.
    """
    code_names = rel_path.split(os.sep)
    code_names[-1] = filename
    return '-'.join(code_names)


def _get_git_current_commit_id(abs_path):
    """Get target's git checkout command list.

    When we run command 'git log -n 1' and get the top first git log record, the
    commit id is next to the specific word 'commit'.

    Args:
        abs_path: a string of the absolute path of the target branch.

    Return:
        The current git commit id.

    Raises:
        Call subprocess.check_output cause subprocess.CalledProcessError.
    """
    cwd = os.getcwd()
    os.chdir(abs_path)
    git_log_cmds = [_GIT, _LOG, '-n', '1']
    try:
        out_put = subprocess.check_output(git_log_cmds).decode("utf-8")
    except subprocess.CalledProcessError:
        logging.error(_GIT_LOG_ERROR)
        raise
    finally:
        os.chdir(cwd)
    com_list = out_put.split()
    return com_list[com_list.index(_COMMIT) + 1]


def _get_commit_id_dictionary():
    """Get commit id from dictionary of key, value 'module': 'commit id'."""
    data_id_dict = {}
    with open(_GIT_COMMIT_ID_JSON, 'r') as jsfile:
        data_id_dict = json.load(jsfile)
    return data_id_dict


def _git_checkout_commit_id(abs_path, commit_id):
    """Command to checkout specific commit id.

    Change directory to the module's absolute path which users want to get its
    specific commit id.

    Args:
        abs_path: the absolute path of the target branch. E.g., abs_path/.git
        commit_id: the commit id users want to checkout.

    Raises:
        Call git checkout commit id failed, raise errors.CommitIDNotExistError.
    """
    git_chekout_cmds = [_GIT, _CHECKOUT, commit_id]
    cwd = os.getcwd()
    try:
        os.chdir(abs_path)
        subprocess.check_output(git_chekout_cmds)
    except subprocess.CalledProcessError:
        err = _COMMIT_ID_NOT_EXIST_ERROR.format(commit_id, abs_path)
        logging.error(err)
        raise errors.CommitIDNotExistError(err)
    finally:
        os.chdir(cwd)


def _git_checkout_target_commit_id(target, commit_id):
    """Command to checkout target commit id.

    Switch code base to specific commit id which is kept in data_id_dict with
    target: commit_id as key: value. If the data is missing in data_id_dict, the
    target isn't a selected golden sample raise error for it.

    Args:
        target: the string of target's module name or module path to checkout
                the relevant git to its specific commit id.
        commit_id: a string represent target's specific commit id.

    Returns:
        current_commit_id: the current commit id of the target which should be
            switched back to.
    """
    atest_module_info = module_info.ModuleInfo()
    _, abs_path = common_util.get_related_paths(atest_module_info, target)
    current_commit_id = _get_git_current_commit_id(abs_path)
    _git_checkout_commit_id(abs_path, commit_id)
    return current_commit_id


def _checkout_baseline_code_to_spec_commit_id():
    """Get a dict of target, commit id listed in baseline_code_commit_id.json.

    To make sure all samples run on the same environment, we need to keep all
    the baseline code in a specific commit id. For example, all samples should
    be created in the same specific commit id of the baseline code
    'frameworks/base' for comparison except 'frameworks/base' itself.

    Returns:
        A dictionary contains target, specific and current commit id.
    """
    spec_and_cur_commit_id_dict = {}
    data_id_dict = _get_commit_id_dictionary()
    for target in data_id_dict:
        commit_id = data_id_dict.get(target, '')
        current_commit_id = _git_checkout_target_commit_id(target, commit_id)
        spec_and_cur_commit_id_dict[target] = {}
        spec_and_cur_commit_id_dict[target]['current'] = current_commit_id
    return spec_and_cur_commit_id_dict


def _generate_target_real_iml_data(target):
    """Generate single target's real iml file content's data.

    Args:
        target: Android module name or path to be create iml data.

    Returns:
        data: A dictionary contains key: unique file name and value: iml
              content.
    """
    data = {}
    try:
        aidegen_main.main([target, '-s', '-n', '-v'])
    except (errors.FakeModuleError,
            errors.ProjectOutsideAndroidRootError,
            errors.ProjectPathNotExistError,
            errors.NoModuleDefinedInModuleInfoError) as err:
        logging.error(str(err))
        return data

    atest_module_info = module_info.ModuleInfo()
    rel_path, abs_path = common_util.get_related_paths(atest_module_info,
                                                       target)
    for filename in iter(_get_project_file_names(abs_path)):
        real_iml_file = os.path.join(abs_path, filename)
        item_name = _get_unique_module_name(rel_path, filename)
        data[item_name] = _import_project_file_xml_etree(real_iml_file)
    return data


def _generate_sample_json(test_list):
    """Generate sample iml data.

    We use all baseline code samples on the version of their own specific commit
    id which is kept in _GIT_COMMIT_ID_JSON file. We need to switch back to
    their current commit ids after generating golden samples' data.

    Args:
        test_list: a list of module name and module path.

    Returns:
        data: a dictionary contains dependent files' data of project file's
              contents.
        The sample is like:
            "frameworks-base.iml": {
                "srcs": [
                    ....
                    "file://$PROJECT_DIR$/frameworks/base/cmds/am/src",
                    "file://$PROJECT_DIR$/frameworks/base/cmds/appwidget/src",
                    ....
                ],
                "jars": [
                    ....
                    "jar://$PROJECT_DIR$/out/target/common/**/aapt2.srcjar!/",
                    ....
                ]
            }
    """
    data = {}
    spec_and_cur_commit_id_dict = _checkout_baseline_code_to_spec_commit_id()
    for target in test_list:
        data.update(_generate_target_real_iml_data(target))
    atest_module_info = module_info.ModuleInfo()
    for target in spec_and_cur_commit_id_dict:
        _, abs_path = common_util.get_related_paths(atest_module_info, target)
        _git_checkout_commit_id(
            abs_path, spec_and_cur_commit_id_dict[target]['current'])
    return data


def _create_some_sample_json_file(targets):
    """Write some samples' iml data into a json file.

    Args:
        targets: Android module name or path to be create iml data.

    linked_function: _generate_sample_json()
    """
    data = _generate_sample_json(targets)
    data_sample = {}
    with open(_GOLDEN_SAMPLES_JSON, 'r') as infile:
        try:
            data_sample = json.load(infile)
        # pylint: disable=maybe-no-member
        except json.JSONDecodeError as err:
            print("Json decode error: {}".format(err))
            data_sample = {}
    data_sample.update(data)
    with open(_GOLDEN_SAMPLES_JSON, 'w') as outfile:
        json.dump(data_sample, outfile, indent=4, sort_keys=False)


def test_samples(func):
    """Decorate a function to deal with preparing and verifying staffs of it.

    Args:
        func: a function is to be compared its iml data with the json file's
              data.

    Returns:
        The wrapper function.
    """

    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        """A wrapper function."""

        test_successful = True
        with open(_GOLDEN_SAMPLES_JSON, 'r') as outfile:
            data_sample = json.load(outfile)

        data_real = func(*args, **kwargs)

        for name in data_real:
            for item in [_SRCS, _JARS]:
                s_items = data_sample[name][item]
                r_items = data_real[name][item]
                if set(s_items) != set(r_items):
                    diff_iter = _compare_content(name, item, s_items, r_items)
                    if diff_iter:
                        print('\n{} {}'.format(
                            common_util.COLORED_INFO('Test error:'),
                            _TEST_ERROR.format(name, item)))
                        print('{} {} contents are different:'.format(
                            name, item))
                        for diff in diff_iter:
                            print(diff)
                        test_successful = False
        if test_successful:
            print(common_util.COLORED_PASS(_ALL_PASS))
        return test_successful

    return wrapper


@test_samples
def _test_some_sample_iml(targets=None):
    """Compare with sample iml's data to assure the project's contents is right.

    Args:
        targets: Android module name or path to be create iml data.
    """
    if targets:
        return _generate_sample_json(targets)
    return _generate_sample_json(_get_commit_id_dictionary().keys())


@test_samples
def _test_all_samples_iml():
    """Compare all imls' data with all samples' data.

    It's to make sure each iml's contents is right. The function is implemented
    but hasn't been used yet.
    """
    all_module_list = module_info.ModuleInfo().name_to_module_info.keys()
    return _generate_sample_json(all_module_list)


def _compare_content(module_name, item_type, s_items, r_items):
    """Compare src or jar files' data of two dictionaries.

    Args:
        module_name: the test module name.
        item_type: the type is src or jar.
        s_items: sample jars' items.
        r_items: real jars' items.

    Returns:
        An iterator of not equal sentences after comparison.
    """
    if item_type == _SRCS:
        cmp_iter1 = _compare_srcs_content(module_name, s_items, r_items,
                                          _MSG_NOT_IN_PROJECT_FILE)
        cmp_iter2 = _compare_srcs_content(module_name, r_items, s_items,
                                          _MSG_NOT_IN_SAMPLE_DATA)
    else:
        cmp_iter1 = _compare_jars_content(module_name, s_items, r_items,
                                          _MSG_NOT_IN_PROJECT_FILE)
        cmp_iter2 = _compare_jars_content(module_name, r_items, s_items,
                                          _MSG_NOT_IN_SAMPLE_DATA)
    return itertools.chain(cmp_iter1, cmp_iter2)


def _compare_srcs_content(module_name, s_items, r_items, msg):
    """Compare src or jar files' data of two dictionaries.

    Args:
        module_name: the test module name.
        s_items: sample jars' items.
        r_items: real jars' items.
        msg: the message will be written into log file.

    Returns:
        An iterator of not equal sentences after comparison.
    """
    for sample in s_items:
        if sample not in r_items:
            yield msg.format(sample, module_name)


def _compare_jars_content(module_name, s_items, r_items, msg):
    """Compare src or jar files' data of two dictionaries.

    AIDEGen treats the jars in folder names 'linux_glib_common' and
    'android_common' as the same content. If the paths are different only
    because of these two names, we ignore it.

    Args:
        module_name: the test module name.
        s_items: sample jars' items.
        r_items: real jars' items.
        msg: the message will be written into log file.

    Returns:
        An iterator of not equal sentences after comparison.
    """
    for sample in s_items:
        if sample not in r_items:
            lnew = sample
            if constant.LINUX_GLIBC_COMMON in sample:
                lnew = sample.replace(constant.LINUX_GLIBC_COMMON,
                                      constant.ANDROID_COMMON)
            else:
                lnew = sample.replace(constant.ANDROID_COMMON,
                                      constant.LINUX_GLIBC_COMMON)
            if not lnew in r_items:
                yield msg.format(sample, module_name)


# pylint: disable=broad-except
# pylint: disable=eval-used
@common_util.back_to_cwd
@common_util.time_logged
def _verify_aidegen(verified_file_path, forced_remove_bp_json,
                    is_presubmit=False):
    """Verify various use cases of executing aidegen.

    There are two types of running commands:
    1. Use 'eval' to run the commands for present codes in aidegen_main.py,
       such as:
           aidegen_main.main(['tradefed', '-n', '-v'])
    2. Use 'subprocess.check_call' to run the commands for the binary codes of
       aidegen such as:
       aidegen tradefed -n -v

    Remove module_bp_java_deps.json in the beginning of running use cases. If
    users need to remove module_bp_java_deps.json between each use case they
    can set forced_remove_bp_json true.

    Args:
        verified_file_path: The json file path to be verified.
        forced_remove_bp_json: Remove module_bp_java_deps.json for each use case
                               test.

    Raises:
        There are two type of exceptions:
        1. aidegen.lib.errors for projects' or modules' issues such as,
           ProjectPathNotExistError.
        2. Any exceptions other than aidegen.lib.errors such as,
           subprocess.CalledProcessError.
    """
    bp_json_path = common_util.get_blueprint_json_path(
        constant.BLUEPRINT_JAVA_JSONFILE_NAME)
    use_eval = (verified_file_path == _VERIFY_COMMANDS_JSON)
    try:
        with open(verified_file_path, 'r') as jsfile:
            data = json.load(jsfile)
    except IOError as err:
        raise errors.JsonFileNotExistError(
            '%s does not exist, error: %s.' % (verified_file_path, err))

    if not is_presubmit:
        _compare_sample_native_content()

    os.chdir(common_util.get_android_root_dir())
    for use_case in data:
        print('Use case "{}" is running.'.format(use_case))
        if forced_remove_bp_json and os.path.exists(bp_json_path):
            os.remove(bp_json_path)
        for cmd in data[use_case]:
            print('Command "{}" is running.'.format(cmd))
            try:
                if use_eval:
                    eval(cmd)
                else:
                    subprocess.check_call(cmd, shell=True)
            except (errors.ProjectOutsideAndroidRootError,
                    errors.ProjectPathNotExistError,
                    errors.NoModuleDefinedInModuleInfoError,
                    errors.IDENotExistError) as err:
                print('"{}" raises error: {}.'.format(use_case, err))
                continue
            except BaseException:
                exc_type, _, _ = sys.exc_info()
                print('"{}.{}" command {}.'.format(
                    use_case, cmd, common_util.COLORED_FAIL('executes failed')))
                raise BaseException(
                    'Unexpected command "{}" exception: {}.'.format(
                        use_case, exc_type))
        print('"{}" command {}!'.format(
            use_case, common_util.COLORED_PASS('test passed')))
    print(common_util.COLORED_PASS(_ALL_PASS))


@common_util.back_to_cwd
def _make_clean():
    """Make a command to clean out folder for a pure environment to test.

    Raises:
        Call subprocess.check_call to execute
        'build/soong/soong_ui.bash --make-mode clean' and cause
        subprocess.CalledProcessError.
    """
    try:
        os.chdir(common_util.get_android_root_dir())
        subprocess.check_call(
            ['build/soong/soong_ui.bash --make-mode clean', '-j'],
            shell=True)
    except subprocess.CalledProcessError:
        print('"build/soong/soong_ui.bash --make-mode clean" command failed.')
        raise


def _read_file_content(path):
    """Read file's content.

    Args:
        path: Path of input file.

    Returns:
        A list of content strings.
    """
    with open(path, encoding='utf8') as template:
        contents = []
        for cnt in template:
            if cnt.startswith('#'):
                continue
            contents.append(cnt.rstrip())
        return contents


# pylint: disable=protected-access
def _compare_sample_native_content():
    """Compares 'libui' sample module's project file.

    Compares 'libui' sample module's project file generated by AIDEGen with that
    generated by the soong build system. Check if their contents are the same.
    There should be only one different:
        ${config.X86_64GccRoot} # in the soong build sytem
        becomes
        prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.9 # in AIDEGen
    """
    target_arch_variant = 'x86_64'
    env_on = {
        'TARGET_PRODUCT': 'aosp_x86_64',
        'TARGET_BUILD_VARIANT': 'eng',
        'TARGET_ARCH_VARIANT': target_arch_variant,
        'SOONG_COLLECT_JAVA_DEPS': 'true',
        'SOONG_GEN_CMAKEFILES': '1',
        'SOONG_COLLECT_CC_DEPS': '1'
    }

    try:
        project_config.ProjectConfig(
            aidegen_main._parse_args(['-n', '-v'])).init_environment()
        module_info_util.generate_merged_module_info(env_on)
        cc_path = os.path.join(common_util.get_soong_out_path(),
                               constant.BLUEPRINT_CC_JSONFILE_NAME)
        mod_name = 'libui'
        mod_info = common_util.get_json_dict(cc_path)['modules'][mod_name]
        if mod_info:
            clion_project_file_gen.CLionProjectFileGenerator(
                mod_info).generate_cmakelists_file()
            out_dir = os.path.join(common_util.get_android_root_dir(),
                                   common_util.get_android_out_dir(),
                                   constant.RELATIVE_NATIVE_PATH,
                                   mod_info['path'][0])
            content1 = _read_file_content(os.path.join(
                out_dir, mod_name, constant.CLION_PROJECT_FILE_NAME))
            cc_file_name = ''.join(
                [mod_name, '-', target_arch_variant, '-android'])
            cc_file_path = os.path.join(
                out_dir, cc_file_name, constant.CLION_PROJECT_FILE_NAME)
            content2 = _read_file_content(cc_file_path)
            same = True
            for lino, (cnt1, cnt2) in enumerate(
                    zip(content1, content2), start=1):
                if _BE_REPLACED in cnt2:
                    cnt2 = cnt2.replace(_BE_REPLACED, _TO_REPLACE)
                if cnt1 != cnt2:
                    print('Contents {} and {} are different in line:{}.'.format(
                        cnt1, cnt2, lino))
                    same = False
            if same:
                print('Files {} and {} are the same.'.format(
                    mod_name, cc_file_name))
    except errors.BuildFailureError:
        print('Compare native content failed.')


def main(argv):
    """Main entry.

    1. Create the iml file data of each module in module-info.json and write it
       into single_module.json.
    2. Verify every use case of AIDEGen.
    3. Compare all or some iml project files' data to the data recorded in
       single_module.json.

    Args:
        argv: A list of system arguments.
    """
    args = _parse_args(argv)
    common_util.configure_logging(args.verbose)
    os.environ[constant.AIDEGEN_TEST_MODE] = 'true'

    if args.make_clean:
        _make_clean()

    if args.create_sample:
        _create_some_sample_json_file(args.targets)
    elif args.use_cases_verified:
        _verify_aidegen(_VERIFY_COMMANDS_JSON, args.remove_bp_json)
    elif args.binary_upload_verified:
        _verify_aidegen(_VERIFY_BINARY_JSON, args.remove_bp_json)
    elif args.binary_presubmit_verified:
        _verify_aidegen(_VERIFY_PRESUBMIT_JSON, args.remove_bp_json, True)
    elif args.test_all_samples:
        _test_all_samples_iml()
    elif args.compare_sample_native:
        _compare_sample_native_content()
    else:
        if not args.targets[0]:
            _test_some_sample_iml()
        else:
            _test_some_sample_iml(args.targets)

    del os.environ[constant.AIDEGEN_TEST_MODE]


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