#!/usr/bin/env perl
# Copyright (c) 2016 - 2021 Advanced Micro Devices, Inc. All rights reserved.
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.

use 5.006; use v5.10.1;
use warnings;
use File::Basename;
use File::Spec;

my $patBUILD = "^".quotemeta(" * BUILD:");
my $patTEST = "^".quotemeta(" * TEST:");
my $patTEST_NAMED = "^".quotemeta(" * TEST_NAMED:");
my $patBUILD_CMD = "^".quotemeta(" * BUILD_CMD:");

# Scan input file for HIT information
sub parse_file {
    my $file = shift;
    (my $exe = $file) =~ s/\.[^.]+$//g;
    my (@buildCMDs, @testCMDs, @testNamedCMDs, @customBuildCMDs);
    if (open (SOURCE, '<:encoding(UTF-8)', "$file")) {
        while (<SOURCE>) {
            my $line=$_;
            # Look for BUILD instructions
            if ($line =~ /$patBUILD/) {
                $line =~ s/^ \* BUILD: //g;     # Remove " * BUILD: "
                $line =~ s/%s/$file/g;          # Substitute %s -> filename
                $line =~ s/%t/$exe/g;           # Substitute %t -> targetname
                $line =~ s/\R//g;               # Remove line endings
                push @buildCMDs, $line;
            }
            # Look for TEST instructions
            if ($line =~ /$patTEST/) {
                $line =~ s/^ \* TEST: //g;      # Remove " * TEST: "
                $line =~ s/%s/$file/g;          # Substitute %s -> filename
                $line =~ s/%t/$exe/g;           # Subsitute %t -> targetname
                $line =~ s/\R//g;               # Remove line endings
                push @testCMDs, $line;
            }
            # Look for TEST_NAMED instructions
            if ($line =~ /$patTEST_NAMED/) {
                $line =~ s/^ \* TEST_NAMED: //g;# Remove " * TEST_NAMED: "
                $line =~ s/%s/$file/g;          # Substitute %s -> filename
                $line =~ s/%t/$exe/g;           # Subsitute %t -> targetname
                $line =~ s/\R//g;               # Remove line endings
                push @testNamedCMDs, $line;
            }
            # Look for BUILD_CMD instructions
            if ($line =~ /$patBUILD_CMD/) {
                $line =~ s/^ \* BUILD_CMD: //g; # Remove " * BUILD_CMD: "
                $line =~ s/%s/$file/g;          # Substitute %s -> filename
                $line =~ s/%t/$exe/g;           # Substitute %t -> targetname
                # Substitute %hc -> /path/to/hipcc and %hip-path -> /path/to/hip happens in cmake
                # Substitute %cc -> cc and %cxx -> c++ happens in cmake
                # Substitute %S -> src dir and %T -> target build dir happens in cmake
                $line =~ s/\R//g;               # Remove line endings
                push @customBuildCMDs, $line;
            }
        }
        close(SOURCE);
    }
    return (\@buildCMDs, \@testCMDs, \@testNamedCMDs, \@customBuildCMDs);
}

# Exit if no arguments specified
if(scalar @ARGV == 0){
    print "No Arguments passed, exiting ...\n";
    exit(-1);
}

# Parse command
my @options = ();
my $retBuildCMDs = 0;
my $retTestCMDs = 0;
my $retTestNamedCMDs = 0;
my $retCustomBuildCMDs = 0;
foreach $arg (@ARGV) {
    if ($retBuildCMDs or $retTestCMDs or $retTestNamedCMDs or $retCustomBuildCMDs) {
        push (@options, $arg);
    }
    if ($arg eq '--buildCMDs') {
        $retBuildCMDs = 1;
    }
    if ($arg eq '--testCMDs') {
        $retTestCMDs = 1;
    }
    if ($arg eq '--testNamedCMDs') {
        $retTestNamedCMDs = 1;
    }
    if ($arg eq '--customBuildCMDs') {
        $retCustomBuildCMDs = 1;
    }
}

# Atleast one command needs to be specified
if (($retBuildCMDs eq 0) and ($retTestCMDs eq 0) and ($retTestNamedCMDs eq 0) and($retCustomBuildCMDs eq 0)) {
    die "Usage: $0 <--buildCMDs|--testCMDs|--testNamedCMDs|--customBuildCMDs> FILENAMEs\n";
}

# Iterate over input files
foreach $file (@options) {
    # Convert absolute path to path relative to working directory
    my $relfile = File::Spec->abs2rel($file);
    my ($buildCMDs, $testCMDs, $testNamedCMDs, $customBuildCMDs) = parse_file("$relfile");
    if ($retBuildCMDs) {
        # print "BuildCMDs:\n";
        print "$_\n" for @$buildCMDs;
    }
    if ($retTestCMDs) {
        # print "TestCMDs:\n";
        print "$_\n" for @$testCMDs;
    }
    if ($retTestNamedCMDs) {
        # print "TestNamedCMDs:\n";
        print "$_\n" for @$testNamedCMDs;
    }
    if ($retCustomBuildCMDs) {
        # print "CustomBuildCMDs:\n";
        print "$_\n" for @$customBuildCMDs;
    }
}

# vim: ts=4:sw=4:expandtab:smartindent
