#!/usr/bin/env python
# Copyright (c) 2013 Google Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
#     * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
#     * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# Used for generating LayoutTest-compatible html files to run html5lib *.dat files.

import os
import glob


class WrapperGenerator(object):
    INPUT_DIRECTORY = "resources"
    INPUT_SUFFIX = ".dat"
    OUTPUT_DIRECTORY = "generated"
    HARNESS_PREFIX = "run-"
    HARNESS_SUFFIX = ".html"
    EXPECTAION_SUFFIX = "-expected.txt"
    HARNESS_TYPES = ("write", "data")

    HARNESS_TEMPLATE = """<!DOCTYPE html>
<script>
var test_files = [ '%(test_path)s' ]
</script>
<script src="../../resources/dump-as-markup.js"></script>
%(extra_content)s
<script src="../resources/runner.js"></script>
"""

    def _files_in_directory_with_suffix(self, directory, suffix):
        return glob.glob(os.path.join(directory, '*' + suffix))

    def _last_path_component_removing_suffix(self, path, suffix):
        return os.path.split(path)[-1][:-len(suffix)]

    def _remove_harness_prefix(self, name):
        assert(name.startswith(self.HARNESS_PREFIX))
        return name[len(self.HARNESS_PREFIX):]

    def _remove_harness_type(self, name):
        parts = name.split('-')
        assert(parts[-1] in self.HARNESS_TYPES)
        return "-".join(parts[:-1])

    def _test_name_from_harness_name(self, name):
        name = self._remove_harness_prefix(name)
        return self._remove_harness_type(name)

    def _remove_stale_tests(self, test_names):
        for path in self._files_in_directory_with_suffix(self.OUTPUT_DIRECTORY, self.HARNESS_SUFFIX):
            name = self._last_path_component_removing_suffix(path, self.HARNESS_SUFFIX)
            name = self._test_name_from_harness_name(name)
            if name not in test_names:
                print("Removing %s, %s no longer exists." % (path, self._input_path(name)))
                os.remove(path)

        for path in self._files_in_directory_with_suffix(self.OUTPUT_DIRECTORY, self.EXPECTAION_SUFFIX):
            name = self._last_path_component_removing_suffix(path, self.EXPECTAION_SUFFIX)
            name = self._test_name_from_harness_name(name)
            if name not in test_names:
                print("Removing %s, %s no longer exists." % (path, self._input_path(name)))
                os.remove(path)

    def _input_path(self, test_name):
        return os.path.join(self.INPUT_DIRECTORY, test_name + self.INPUT_SUFFIX)

    def _harness_path(self, test_name, use_write):
        harness_path = os.path.join(self.OUTPUT_DIRECTORY, self.HARNESS_PREFIX + test_name)
        if use_write:
            harness_path += "-write"
        else:
            harness_path += "-data"
        return harness_path + self.HARNESS_SUFFIX

    def _harness_content(self, test_name, use_write):
        extra_content = ""
        if not use_write:
            extra_content = "<script>window.forceDataURLs = true;</script>";
        return self.HARNESS_TEMPLATE % {
            # FIXME: .. should be relative to the number of components in OUTPUT_DIRECTORY
            'test_path': os.path.join('..', self._input_path(test_name)),
            'extra_content': extra_content,
        }

    def _write_harness(self, test_name, use_write):
        harness_file = open(self._harness_path(test_name, use_write), "w")
        harness_file.write(self._harness_content(test_name, use_write))

    def main(self):
        test_names = [self._last_path_component_removing_suffix(path, self.INPUT_SUFFIX) for path in self._files_in_directory_with_suffix(self.INPUT_DIRECTORY, self.INPUT_SUFFIX)]

        self._remove_stale_tests(test_names)

        for name in test_names:
            self._write_harness(name, True)
            self._write_harness(name, False)


if __name__ == "__main__":
    WrapperGenerator().main()
