# 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.

"""generates webgl layout tests from the Khronos WebGL Conformance Tests"""

# To use this, get a copy of the WebGL conformance tests then run this script
# eg.
#
#   cd ~/temp
#   git clone git://github.com/KhronosGroup/WebGL.git
#   cd ~/WebKit/LayoutTests/webgl
#   python generate-webgl-tests.py -w ~/temp/WebGL/sdk/tests -e
#
# Now check run the LayoutTests, update TestExpectations and check in the
# result.

import copy
import os
import os.path
import sys
import re
import json
import shutil
from optparse import OptionParser

if sys.version < '2.6':
  print 'Wrong Python Version !!!: Need >= 2.6'
  sys.exit(1)


GLOBAL_OPTIONS = {
  # version use. Tests at or below this will be included.
  "version": "1.0.3",

  # version used for unlabled tests
  "default-version": "1.0",

  # If set, the version we require. Tests below this will be ignored.
  "min-version": "1.0.3",
}


def ReadFile(filename):
  """Reads a file as a string"""
  file = open(filename, "r")
  data = file.read()
  file.close()
  return data


def WriteFile(filename, data):
  """Writes a string as a file"""
  print "Writing: ", filename
  dirname = os.path.dirname(filename)
  if not os.path.exists(dirname):
    os.makedirs(dirname)
  file = open(filename, "wb")
  file.write(data)
  file.close()


def CopyTree(src, dst, ignore=None):
  """Recursively copy a directory tree"""
  names = os.listdir(src)
  if ignore is not None:
    ignored_names = ignore(src, names)
  else:
    ignored_names = set()

  if not os.path.exists(dst):
    os.makedirs(dst)
  errors = []
  for name in names:
    if name in ignored_names:
      continue
    srcname = os.path.join(src, name)
    dstname = os.path.join(dst, name)
    try:
      if os.path.isdir(srcname):
        CopyTree(srcname, dstname, ignore)
      else:
        # Will raise a SpecialFileError for unsupported file types
        shutil.copyfile(srcname, dstname)
    # catch the Error from the recursive copytree so that we can
    # continue with other files
    except Error, err:
      errors.extend(err.args[0])
    except EnvironmentError, why:
      errors.append((srcname, dstname, str(why)))
  if errors:
    raise Error, errors


def FileReader(filename):
  """A File generator that returns only non empty, non comment lines"""
  file = open(filename, "r")
  lines = file.readlines()
  file.close()
  for line_number, line in enumerate(lines):
    line = line.strip()
    if (len(line) > 0 and
        not line.startswith("#") and
        not line.startswith(";") and
        not line.startswith("//")):
      yield line_number + 1, line


def GreaterThanOrEqualToVersion(have, want):
  """Compares to version strings"""
  have = have.split(" ")[0].split(".")
  want = want.split(" ")[0].split(".")
  for ndx, want_str in enumerate(want):
    want_num = int(want_str)
    have_num = 0
    if ndx < len(have):
      have_num = int(have[ndx])
    if have_num < want_num:
      return False
  return True


def GetTestList(list_filename, dest_dir, hierarchical_options):
  global GLOBAL_OPTIONS
  tests = []
  prefix = os.path.dirname(list_filename)
  for line_number, line in FileReader(list_filename):
    args = line.split()
    test_options = {}
    non_options = []
    use_test = True
    while len(args):
      arg = args.pop(0)
      if arg.startswith("-"):
        if not arg.startswith("--"):
          raise "%s:%d bad option" % (list_filename, line_number)
        option = arg[2:]
        if option == 'slow':
          pass
        elif option == 'min-version' or option == "max-version":
          test_options[option] = args.pop(0)
        else:
          raise Exception("%s:%d unknown option '%s'" % (list_filename, line_number, arg))
      else:
        non_options.append(arg)
    url = os.path.join(prefix, " ".join(non_options))

    if not url.endswith(".txt"):
      if "min-version" in test_options:
        min_version = test_options["min-version"]
      else:
        min_version = hierarchical_options["default-version"]

      if "min-version" in GLOBAL_OPTIONS:
        use_test = GreaterThanOrEqualToVersion(min_version, GLOBAL_OPTIONS["min-version"])
      else:
        use_test = GreaterThanOrEqualToVersion(GLOBAL_OPTIONS["version"], min_version)

    if not use_test:
      continue

    if url.endswith(".txt"):
      if "min-version" in test_options:
        hierarchical_options["default-version"] = test_options["min-version"]
      tests = tests + GetTestList(
          os.path.join(prefix, url), dest_dir, copy.copy(hierarchical_options))
    else:
      tests.append({"url": url})
  return tests


def main(argv):
  """This is the main function."""
  global GLOBAL_OPTIONS

  parser = OptionParser()
  parser.add_option(
      "-v", "--verbose", action="store_true",
      help="prints more output.")
  parser.add_option(
      "-w", "--webgl-conformance-test", dest="source_dir",
      help="path to webgl conformance tests. REQUIRED")
  parser.add_option(
      "-n", "--no-copy", action="store_true",
      help="do not copy tests")
  parser.add_option(
      "-e", "--generate-expectations", action="store_true",
      help="generatet the test expectations")

  (options, args) = parser.parse_args(args=argv)

  if not options.source_dir:
    parser.print_help()
    return 1

  os.chdir(os.path.dirname(__file__) or '.')

  source_dir = options.source_dir;
  webgl_tests_dir = "resources/webgl_test_files"
  base_path = "."

  # copy all the files from the WebGL conformance tests.
  if not options.no_copy:
    CopyTree(
        source_dir, webgl_tests_dir, shutil.ignore_patterns(
            '.git', '*.pyc', 'tmp*'))

  test_template = ReadFile("resources/webgl-wrapper-template.html")
  expectation_template = ReadFile("resources/webgl-expectation-template.txt")

  # generate wrappers for all the tests
  tests = GetTestList(os.path.join(source_dir, "00_test_list.txt"), ".",
                      copy.copy(GLOBAL_OPTIONS))

  for test in tests:
    url = os.path.relpath(test["url"], source_dir)
    dst = url
    dst_dir = os.path.dirname(dst)
    src = os.path.relpath(os.path.join(webgl_tests_dir, url), dst_dir).replace("\\", "/")
    base_url = os.path.relpath(base_path, dst_dir).replace("\\", "/")
    subs = {
      "url": src,
      "url_name": os.path.basename(url),
      "base_url": base_url,
    }
    WriteFile(dst, test_template % subs)
    if options.generate_expectations:
      expectation_filename = os.path.splitext(dst)[0] + "-expected.txt"
      WriteFile(expectation_filename, expectation_template % subs)



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





