#!/usr/bin/env perl

# Copyright (C) 2005-2021 Apple 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:
#
# 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. 
# 3.  Neither the name of Apple Inc. ("Apple") 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 APPLE 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 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 File::Spec;
use FindBin;
use lib $FindBin::Bin;
use webkitdirs;

my $programName = basename($0);
my $usage = <<EOF;
Usage: $programName [options]
  --32-bit                           Set the default architecture to 32-bit
  --64-bit                           Set the default architecture to 64-bit
  --[no-]asan                        Enable or disable clang address sanitizer
  --[no-]tsan                        Enable or disable clang thread sanitizer
  --[no-]ubsan                       Enable or disable clang undefined behavior sanitizer
  --[no-]coverage                    Enable or disable LLVM Source-based Code Coverage
  --force-optimization-level=<level> Optimization level: O3, O2, O1, O0, Os, Ofast, Og, or none
  --lto-mode=<mode>                  Set LTO mode: full, thin, or none
  --debug                            Set the default configuration to debug
  --release                          Set the default configuration to release
  --reset                            Reset configurations
EOF

sub printCurrentSettings();
sub printUsage();
sub updateOrDeleteConfigurationFile($$$);

my $configuration = passedConfiguration();
my $architecture = passedArchitecture();
my $enableASAN = checkForArgumentAndRemoveFromARGV("--asan");
my $disableASAN = checkForArgumentAndRemoveFromARGV("--no-asan");
my $enableTSAN = checkForArgumentAndRemoveFromARGV("--tsan");
my $disableTSAN = checkForArgumentAndRemoveFromARGV("--no-tsan");
my $enableUBSAN = checkForArgumentAndRemoveFromARGV("--ubsan");
my $disableUBSAN = checkForArgumentAndRemoveFromARGV("--no-ubsan");
my $enableCoverage = checkForArgumentAndRemoveFromARGV("--coverage");
my $disableCoverage = checkForArgumentAndRemoveFromARGV("--no-coverage");
my $ltoMode;
if (!checkForArgumentAndRemoveFromARGVGettingValue("--lto-mode", \$ltoMode)) {
    $ltoMode="";
}
my $forceOptimizationLevel;
if (!checkForArgumentAndRemoveFromARGVGettingValue("--force-optimization-level", \$forceOptimizationLevel)
    && !checkForArgumentAndRemoveFromARGVGettingValue("--force-opt", \$forceOptimizationLevel)) {
    $forceOptimizationLevel="";
}

if (!$architecture) {
    # Handle --64-bit explicitly here, as we don't want our other scripts to accept it
    for my $i (0 .. $#ARGV) {
        my $opt = $ARGV[$i];
        if ($opt =~ /^--64-bit$/i) {
            splice(@ARGV, $i, 1);
            $architecture = 'x86_64';
        }
    }
}

my $baseProductDir = baseProductDir();
system "mkdir", "-p", "$baseProductDir";

if (checkForArgumentAndRemoveFromARGV("--reset")) {
    for my $fileName (qw(Architecture ASan Configuration Coverage ForceOptimizationLevel LTO TSan UBSan)) {
        unlink File::Spec->catfile($baseProductDir, $fileName);
    }
    printCurrentSettings();
    exit 0;
}

if ((!$configuration && !$architecture && !$enableASAN && !$disableASAN && !$enableCoverage && !$disableCoverage && !$enableTSAN && !$disableTSAN && !$enableUBSAN && !$disableUBSAN && !$ltoMode && !$forceOptimizationLevel)
    || ($enableASAN && $disableASAN)
    || ($enableCoverage && $disableCoverage)
    || ($enableTSAN && $disableTSAN)
    || ($enableUBSAN && $disableUBSAN)
    ) {
    printUsage();
    exit 1;
}

if ($enableASAN && $enableTSAN) {
    print STDERR "ERROR: Address Sanitizer and Thread Sanitzer can't be enabled together.\n";
    printUsage();
    exit 1;
}

if ($ltoMode && $ltoMode ne "full" && $ltoMode ne "thin" && $ltoMode ne "none") {
    printUsage();
    exit 1;
}

if ($forceOptimizationLevel
    && $forceOptimizationLevel ne "none"
    && $forceOptimizationLevel ne "O0"
    && $forceOptimizationLevel ne "O1"
    && $forceOptimizationLevel ne "O2"
    && $forceOptimizationLevel ne "O3"
    && $forceOptimizationLevel ne "Os"
    && $forceOptimizationLevel ne "Ofast"
    && $forceOptimizationLevel ne "Og") {
    printUsage();
    exit 1;
}

if ($configuration) {
    open CONFIGURATION, ">", "$baseProductDir/Configuration" or die;
    print CONFIGURATION $configuration;
    close CONFIGURATION;
}

if ($architecture) {
    if ($architecture ne "x86_64") {
        open ARCHITECTURE, ">", "$baseProductDir/Architecture" or die;
        print ARCHITECTURE $architecture;
        close ARCHITECTURE;
    } else {
        unlink "$baseProductDir/Architecture";
    }
}

updateOrDeleteConfigurationFile("ASan", $enableASAN, $disableASAN);
updateOrDeleteConfigurationFile("Coverage", $enableCoverage, $disableCoverage);
updateOrDeleteConfigurationFile("TSan", $enableTSAN, $disableTSAN);
updateOrDeleteConfigurationFile("UBSan", $enableUBSAN, $disableUBSAN);

if ($forceOptimizationLevel && $forceOptimizationLevel eq "none") {
    unlink "$baseProductDir/ForceOptimizationLevel";
} elsif ($forceOptimizationLevel) {
    open ForceOptimizationLevel, ">", "$baseProductDir/ForceOptimizationLevel" or die;
    print ForceOptimizationLevel substr($forceOptimizationLevel, 1) . "\n";
    close ForceOptimizationLevel;
}

if ($ltoMode) {
    open LTO, ">", "$baseProductDir/LTO" or die;
    print LTO "$ltoMode";
    close LTO;
}

printCurrentSettings();

exit 0;

sub printCurrentSettings()
{
    my $result = "Current settings:";
    $result .= " Configuration:" . configuration();
    $result .= " Arch:" . architecture() if architecture();
    $result .= " ASan" if asanIsEnabled();
    $result .= " TSan" if tsanIsEnabled();
    $result .= " UBSan" if ubsanIsEnabled();
    $result .= " Coverage" if coverageIsEnabled();
    $result .= " LTOMode:" . ltoMode() if ltoMode();
    $result .= " ForceOptimizationLevel:O" . forceOptimizationLevel() if forceOptimizationLevel();

    print STDERR $result, "\n";
}

sub printUsage()
{
    print STDERR $usage, "\n";
    printCurrentSettings();
}

sub updateOrDeleteConfigurationFile($$$)
{
    my ($fileName, $shouldEnable, $shouldDisable) = @_;
    my $filePath = File::Spec->catfile($baseProductDir, $fileName);
    if ($shouldEnable) {
       open FILE, ">", $filePath or die;
       print FILE "YES";
       close FILE;
    } elsif ($shouldDisable) {
        unlink $filePath;
    }
}
