#!/usr/bin/env perl
#
# Copyright (C) 2016 Sony Interactive Entertainment Inc.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1.  Redistributions of source code must retain the above copyright
#     notice, this list of conditions and the following disclaimer.
# 2.  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.
#
# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS 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 APPLE INC. OR ITS 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.
#

use strict;
use warnings;
use FindBin;
use lib $FindBin::Bin;

use File::Basename;
use File::Spec;
use File::Find;
use Getopt::Long;

my $perl = $^X;
my $scriptDir = $FindBin::Bin;
my @idlDirectories;
my $outputDirectory;
my $idlFilesList;
my $ppIDLFilesList;
my $generator;
my @generatorDependency;
my $defines;
my $preprocessor;
my $supplementalDependencyFile;
my @ppExtraOutput;
my @ppExtraArgs;
my $numOfJobs = 1;
my $idlAttributesFile;
my $showProgress;

GetOptions('include=s@' => \@idlDirectories,
           'outputDir=s' => \$outputDirectory,
           'idlFilesList=s' => \$idlFilesList,
           'ppIDLFilesList=s' => \$ppIDLFilesList,
           'generator=s' => \$generator,
           'generatorDependency=s@' => \@generatorDependency,
           'defines=s' => \$defines,
           'preprocessor=s' => \$preprocessor,
           'supplementalDependencyFile=s' => \$supplementalDependencyFile,
           'ppExtraOutput=s@' => \@ppExtraOutput,
           'ppExtraArgs=s@' => \@ppExtraArgs,
           'idlAttributesFile=s' => \$idlAttributesFile,
           'numOfJobs=i' => \$numOfJobs,
           'showProgress' => \$showProgress);

$| = 1;
my @idlFiles;
open(my $fh, '<', $idlFilesList) or die "Cannot open $idlFilesList";
@idlFiles = map { CygwinPathIfNeeded(s/\r?\n?$//r) } <$fh>;
close($fh) or die;

my @ppIDLFiles;
open($fh, '<', $ppIDLFilesList) or die "Cannot open $ppIDLFilesList";
@ppIDLFiles = map { CygwinPathIfNeeded(s/\r?\n?$//r) } <$fh>;
close($fh) or die;

my %oldSupplements;
my %newSupplements;
if ($supplementalDependencyFile) {
    my @output = ($supplementalDependencyFile, @ppExtraOutput);
    my @deps = ($ppIDLFilesList, @ppIDLFiles, @generatorDependency);
    if (needsUpdate(\@output, \@deps)) {
        readSupplementalDependencyFile($supplementalDependencyFile, \%oldSupplements) if -e $supplementalDependencyFile;
        my @args = (File::Spec->catfile($scriptDir, 'preprocess-idls.pl'),
                    '--defines', $defines,
                    '--idlFileNamesList', $ppIDLFilesList,
                    '--supplementalDependencyFile', $supplementalDependencyFile,
                    '--idlAttributesFile', $idlAttributesFile,
                    @ppExtraArgs);
        printProgress("Preprocess IDL");
        executeCommand($perl, @args) == 0 or die;
    }
    readSupplementalDependencyFile($supplementalDependencyFile, \%newSupplements);
}

my @args = (File::Spec->catfile($scriptDir, 'generate-bindings.pl'),
            '--defines', $defines,
            '--generator', $generator,
            '--outputDir', $outputDirectory,
            '--preprocessor', $preprocessor,
            '--idlAttributesFile', $idlAttributesFile,
            '--write-dependencies');
push @args, map { ('--include', $_) } @idlDirectories;
push @args, '--supplementalDependencyFile', $supplementalDependencyFile if $supplementalDependencyFile;

my %directoryCache;
buildDirectoryCache();

my @idlFilesToUpdate = grep &{sub {
    if (defined($oldSupplements{$_})
        && @{$oldSupplements{$_}} ne @{$newSupplements{$_} or []}) {
        # Re-process the IDL file if its supplemental dependencies were added or removed
        return 1;
    }
    my ($filename, $dirs, $suffix) = fileparse($_, '.idl');
    my $sourceFile = File::Spec->catfile($outputDirectory, "JS$filename.cpp");
    my $headerFile = File::Spec->catfile($outputDirectory, "JS$filename.h");
    my $depFile = File::Spec->catfile($outputDirectory, "JS$filename.dep");
    my @output = ($sourceFile, $headerFile);
    my @deps = ($_,
                $idlAttributesFile,
                @generatorDependency,
                @{$newSupplements{$_} or []},
                implicitDependencies($depFile));
    needsUpdate(\@output, \@deps);
}}, @idlFiles;

my $abort = 0;
my $totalCount = @idlFilesToUpdate;
my $currentCount = 0;

spawnGenerateBindingsIfNeeded() for (1 .. $numOfJobs);
while (waitpid(-1, 0) != -1) {
    if ($?) {
        $abort = 1;
    }
    spawnGenerateBindingsIfNeeded();
}
exit $abort;

sub needsUpdate
{
    my ($objects, $depends) = @_;
    my $oldestObjectTime;
    for (@$objects) {
        return 1 if !-f;
        my $m = mtime($_);
        if (!defined $oldestObjectTime || $m < $oldestObjectTime) {
            $oldestObjectTime = $m;
        }
    }
    for (@$depends) {
        die "Missing required dependency: $_" if !-f;
        my $m = mtime($_);
        if ($oldestObjectTime < $m) {
            return 1;
        }
    }
    return 0;
}

sub mtime
{
    my ($file) = @_;
    return (stat $file)[9];
}

sub spawnGenerateBindingsIfNeeded
{
    return if $abort;
    return unless @idlFilesToUpdate;
    my $batchCount = 30;
    # my $batchCount = int(($totalCount - $currentCount) / $numOfJobs) || 1;
    my @files = splice(@idlFilesToUpdate, 0, $batchCount);
    for (@files) {
        $currentCount++;
        my $basename = basename($_);
        printProgress("[$currentCount/$totalCount] $basename");
    }
    my $pid = spawnCommand($perl, @args, @files);
    $abort = 1 unless defined $pid;
}

sub buildDirectoryCache
{
    my $wanted = sub {
        $directoryCache{$_} = $File::Find::name;
        $File::Find::prune = 1 unless ~/\./;
    };
    find($wanted, @idlDirectories);
}

sub implicitDependencies
{
    my ($depFile) = @_;
    return () unless -f $depFile;
    open(my $fh, '<', $depFile) or die "Cannot open $depFile";
    my $firstLine = <$fh>;
    close($fh) or die;
    my (undef, $deps) = split(/ : /, $firstLine);
    my @deps = split(/\s+/, $deps);
    return map { $directoryCache{$_} or () } @deps;
}

sub executeCommand
{
    if ($^O eq 'MSWin32') {
        return system(quoteCommand(@_));
    }
    return system(@_);
}

sub spawnCommand
{
    my $pid = fork();
    if ($pid == 0) {
        @_ = quoteCommand(@_) if ($^O eq 'MSWin32');
        exec(@_);
        die "Cannot exec";
    }
    return $pid;
}

sub quoteCommand
{
    return map {
        '"' . s/([\\\"])/\\$1/gr . '"';
    } @_;
}

sub CygwinPathIfNeeded
{
    my $path = shift;
    return Cygwin::win_to_posix_path($path) if ($^O eq 'cygwin');
    return $path;
}

sub readSupplementalDependencyFile
{
    my $filename = shift;
    my $supplements = shift;
    open(my $fh, '<', $filename) or die "Cannot open $filename";
    while (<$fh>) {
        my ($idlFile, @followingIdlFiles) = split(/\s+/);
        $supplements->{$idlFile} = [sort @followingIdlFiles];
    }
    close($fh) or die;
}

sub printProgress
{
    return unless $showProgress;
    my $msg = shift;
    print "$msg\n";
}
