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


import os
import subprocess

from optparse import OptionParser

def chdir_to_source():
    source_directory = os.path.abspath(os.path.join(__file__, '..', '..'))
    os.chdir(source_directory)

def gyp():
    return os.path.join('ThirdParty', 'gyp', 'gyp')

class Project:
    def __init__(self, name):
        self._name = name

    def name(self):
        return self._name

    def inputs(self):
        return [
            os.path.join(self._name, 'gyp', self._name + '.gyp'),
            os.path.join(self._name, self._name + '.gypi'),
            os.path.join('gyp', 'common.gypi'),
        ]

    def output(self):
        return os.path.join(self._name, 'gyp', self._name + '.xcodeproj', 'project.pbxproj')

    def should_generate(self):
        if not os.path.exists(self.output()):
            return True
        return os.path.getmtime(self.output()) < self._newest(self.inputs())

    def generate(self):
        subprocess.call([
            gyp(),
            self.inputs()[0],
            '-G',
            'xcode_list_excluded_files=0',
            '--depth=.',
        ])
        # GYP doesn't always touch the output file, but we want to touch the
        # file so that we don't keep trying to regenerate it.
        os.utime(self.output(), None)

    @staticmethod
    def _newest(paths):
        return max([os.path.getmtime(path) for path in paths])

PROJECTS = [
    Project("JavaScriptCore"),
    Project("WebCore"),
]

def projects_to_generate():
    should_generate = [project for project in PROJECTS if project.should_generate()]
    already_generated = [project.name() for project in set(PROJECTS) - set(should_generate)]

    if already_generated:
        print "Not generating %s because the generated files exist and are newer than the GYP files." % ', '.join(already_generated)
        print "Pass --regenerate-projects to override."

    return should_generate

def main():
    chdir_to_source()

    parser = OptionParser()
    # FIXME: The user should be able to pass which port on the command line.
    parser.add_option("--regenerate-projects", dest="regenerate_projects",
                      default=False, action="store_true",
                      help="Generate all project files even if they appear to be up to date.")
    (options, args) = parser.parse_args()

    projects = PROJECTS
    if not options.regenerate_projects:
        projects = projects_to_generate()

    for project in projects:
        print "Generating %s." % project.name()
        project.generate()

if __name__ == "__main__":
    main()
