# Copyright 2016 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Script to generate Web Bluetooth Layout Tests that can be run in ClusterFuzz.

This script uses templates in the templates/ directory to generate html files
that can be run as Layout Tests. The script reads a template, includes files
necessary to run as a layout test, fuzzes its parameters and saves the result in
a new file in the directory specified when running the script.
"""

import argparse
import glob
import os
import sys
import tempfile
import time

from fuzzer_helpers import FillInParameter
import parameter_fuzzer
import test_case_fuzzer

JS_FILES_AND_PARAMETERS = (
    ('testharness.js', 'INCLUDE_TESTHARNESS'),
    ('testharnessreport.js', 'INCLUDE_REPORT'),
    ('bluetooth-helpers.js', 'INCLUDE_BLUETOOTH_HELPERS'))

SCRIPT_PREFIX = '<script type="text/javascript">\n'
SCRIPT_SUFFIX = '\n</script>\n'


def _GetArguments():
    """Parses the arguments passed when running this script.

    Returns:
      An argparse.Namespace object containing the arguments in sys.argv.
    """
    parser = argparse.ArgumentParser()

    # Arguments used by ClusterFuzz:
    parser.add_argument('-n', '--no_of_files', type=int, required=True,
                        help='The number of test cases that the fuzzer is '
                             'expected to generate')
    parser.add_argument('-i', '--input_dir',
                        help='The directory containing the fuzzer\'s data '
                             'bundle.')
    parser.add_argument('-o', '--output_dir', required=True,
                        help='The directory where test case files should be '
                             'written to.')

    parser.add_argument('--content_shell_dir',
                        help='The directory of content shell. If present the '
                             'program will print a command to run the '
                             'generated test file.')

    return parser.parse_args()


def FuzzTemplate(template_path, resources_path):
    """Uses a template to return a test case that can be run as a layout test.

    This functions reads the template in |template_path|, injects the necessary
    js files to run as a layout test and fuzzes the template's parameters to
    generate a test case.

    Args:
      template_path: The path to the template that will be used to generate
          a new test case.
      resources_path: Path to the js files that need to be included.

    Returns:
      A string containing the test case.
    """
    print 'Generating test file based on {}'.format(template_path)

    # Read the template.
    template_file_handle = open(template_path)
    template_file_data = template_file_handle.read().decode('utf-8')
    template_file_handle.close()

    # Generate a test file based on the template.
    generated_test = test_case_fuzzer.GenerateTestFile(template_file_data)
    # Fuzz parameters.
    fuzzed_file_data = parameter_fuzzer.FuzzParameters(generated_test)

    # Add includes
    for (js_file_name, include_parameter) in JS_FILES_AND_PARAMETERS:
        # Read js file.
        js_file_handle = open(os.path.join(resources_path, js_file_name))
        js_file_data = js_file_handle.read()
        js_file_handle.close()

        js_file_data = (SCRIPT_PREFIX + js_file_data + SCRIPT_SUFFIX)

        fuzzed_file_data = FillInParameter(include_parameter,
                                           lambda data=js_file_data: data,
                                           fuzzed_file_data)

    return fuzzed_file_data.encode('utf-8')


def WriteTestFile(test_file_data, test_file_prefix, output_dir):
    """Creates a new file with a unique name and writes the test case to it.

    Args:
      test_file_data: The data to be included in the new file.
      test_file_prefix: Used as a prefix when generating a new file.
      output_dir: The directory where the new file should be created.

    Returns:
      A string representing the file path to access the new file.
    """

    file_descriptor, file_path = tempfile.mkstemp(
        prefix=test_file_prefix,
        suffix='.html',
        dir=output_dir)

    with os.fdopen(file_descriptor, 'wb') as output:
        print 'Writing {} bytes to \'{}\''.format(len(test_file_data),
                                                  file_path)
        output.write(test_file_data)

    return file_path


def main():
    args = _GetArguments()

    print 'Generating {} test file(s).'.format(args.no_of_files)
    print 'Writing test files to: \'{}\''.format(args.output_dir)
    if args.input_dir:
        print 'Reading data bundle from: \'{}\''.format(args.input_dir)

    # Get Templates
    current_path = os.path.dirname(os.path.realpath(__file__))
    available_templates = glob.glob(os.path.join(current_path,
                                                 'templates',
                                                 '*.html'))

    # Generate Test Files
    resources_path = os.path.join(current_path, 'resources')
    start_time = time.time()
    for file_no in range(args.no_of_files):
        template_path = available_templates[file_no % len(available_templates)]

        test_file_data = FuzzTemplate(template_path, resources_path)

        # Get Test File
        template_name = os.path.splitext(os.path.basename(template_path))[0]
        test_file_name = 'fuzz-{}-{}-{}'.format(template_name,
                                                int(start_time),
                                                int(file_no))

        test_file_path = WriteTestFile(test_file_data,
                                       test_file_name,
                                       args.output_dir)

        if args.content_shell_dir:
            print '{} --run-layout-test {}'.format(args.content_shell_dir,
                                                   test_file_path)


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