#!/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/', '/resources/'),
        ('\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)
