#!/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 _gyp_directory(self):
        return os.path.join(self._name, 'gyp')

    def _gyp_file_for_port(self, port):
        # Gyp uses the gyp file name as the XCode proj file name, so for now "apple-mac" must be ProjectName.gyp
        if port == "mac":
            return '%s.gyp' % self._name
        return "%s.gyp" % port

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

    def _output_for_port(self, port):
        format = format_for_port(port)
        return {
            'filelist': '%s.am' % port,
            'xcode': os.path.join(self._name + '.xcodeproj', 'project.pbxproj'),
        }[format]

    def output(self, port):
        return os.path.join(self._gyp_directory(), self._output_for_port(port))

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

    def _extra_args_for_format(self, format):
        if format == "xcode":
            return ['-G', 'xcode_list_excluded_files=0']
        return []

    def generate(self, port):
        args = [
            gyp(),
            self.inputs(port)[0],
            '--depth=.',
        ]
        format = format_for_port(port)
        args.append('--format=%s' % format)
        args += self._extra_args_for_format(format)

        subprocess.call(args)
        # 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(port), None)

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


def format_for_port(port):
    return {
        'mac': 'xcode',
        'gtk': 'filelist',
        'win': 'msvs',
    }[port] # Valid port is required.


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

def projects_to_generate(port):
    should_generate = [project for project in PROJECTS if project.should_generate(port)]
    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()
    parser.add_option("--port", dest="port", action="store", default="mac", # Default to Mac for now
                      help="Which port to generate for.")
    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(options.port)

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


if __name__ == "__main__":
    main()
