#!/usr/bin/env python
# Copyright (C) 2012 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.

# This script exports newly added tests to the W3C Web Performance WG's test
# suite.
#
# You must have checked out the 'webperf' repository from https://dvcs.w3.org/hg/
#
# This script will export the LayoutTests/http/tests/w3c/submission directory
# to a local 'webperf' repository.
#
# The main step in exporting the tests is updating all of the URLs to account
# for the differences in directory layout.

import os
import shutil
import sys

if len(sys.argv) != 3:
    print('USAGE: %s path_to_webkit_checkout_root path_to_webperf_checkout_root' % sys.argv[0])
    sys.exit(1)

source_directory = os.path.join(sys.argv[1], 'LayoutTests', 'http', 'tests', 'w3c', 'webperf')
destination_directory = os.path.join(sys.argv[2], 'tests')

directories_to_copy = ['resources', 'submission']
replacements = [
        ('localhost:8000', 'www.w3c-test.org'),   # This is the alternate host for cross-server requests.
        ('127.0.0.1:8000', 'w3c-test.org'),       # This is the primary test server.
        ('w3c/webperf', 'webperf/tests'),         # We prepend /w3c to all of our paths.
        ('/w3c/resources/testharness', '/resources/testharness'),
        ('\n', '\r\n'),                           # Convert from *NIX format.
]

for directory_to_copy in directories_to_copy:
    destination_subdirectory = os.path.join(destination_directory, directory_to_copy)
    if not os.path.exists(destination_subdirectory):
        os.makedirs(destination_subdirectory)
    for root, dirs, files in os.walk(os.path.join(source_directory, directory_to_copy)):
        root = os.path.relpath(root, source_directory)
        for dirname in dirs:
            destination_subdirectory = os.path.join(destination_directory, root, dirname)
            if not os.path.exists(destination_subdirectory):
                os.makedirs(destination_subdirectory)
        for filename in files:
            if filename.endswith('-expected.txt'):
                continue
            with open(os.path.join(source_directory, root, filename), 'r') as in_file:
                with open(os.path.join(destination_directory, root, filename), 'w') as out_file:
                    for line in in_file:
                        for to_find, replace_with in replacements:
                            line = line.replace(to_find, replace_with)
                        out_file.write(line)
                print('Exported %s' % os.path.join(root, filename))
