#!/usr/bin/perl -w

# SPDX-FileCopyrightText: 2006-2021 Istituto Italiano di Tecnologia (IIT)
# SPDX-License-Identifier: BSD-3-Clause


my $verbose_output = 0;

sub print_if_verbose
{
    if ($verbose_output) {
        print (@_);
    }
    return;
}


my @files = `git ls-files src example tests scripts cmake bindings data CMakeLists.txt`;
s{^\s+|\s+$}{}g foreach @files;

open my $handle, '<', "tests/misc/check_style_skip.txt";
chomp(my @skip_files = <$handle>);
close $handle;

my $files = 0;
my $ok = 0;
my $skip = 0;
my $errors = 0;
my $known = 0;

foreach my $filename (@files) {
    $files++;

    # For now skip files known to have a broken style
    my $match = 0;
    for (@skip_files) {
        if ("$filename" eq "$_") {
            $match = 1;
            last;
        }
    }

    if( $match ) {
        print_if_verbose "[SKIP (known)] $filename\n";
        $known++;
        next;
    }

    # Skip images and binary files
    if ("$filename" =~ /\.(png|svg|jpg|ppm|pgm|bmp|ico|icns)$/) {
        print_if_verbose "[SKIP (image - $1)] $filename\n";
        $skip++;
        next;
    }

    if ("$filename" =~ /\.(avi)$/) {
        print_if_verbose "[SKIP (video - $1)] $filename\n";
        $skip++;
        next;
    }

    if ("$filename" =~ /\.(wav)$/) {
        print_if_verbose "[SKIP (audio - $1)] $filename\n";
        $skip++;
        next;
    }

    if ("$filename" =~ /\.(rar)$/) {
        print_if_verbose "[SKIP (binary - $1)] $filename\n";
        $skip++;
        next;
    }

    # Skip autogenerated files
    if ("$filename" =~ /\/src_gen\// ||
        "$filename" =~ /\/qtquick2applicationviewer\// ||
        "$filename" =~ /\/idl_generated_code\//) {
        print_if_verbose "[SKIP (autogen)] $filename\n";
        $skip++;
        next;
    }

    # Read the file
    my $txt = "";
    open(FIN,"<$filename");
    while (<FIN>) {
        $txt .= $_;
    }
    close(FIN);


    # Check if the file contains the unicode BOM
    if ("$txt" =~ /^\xEF\xBB\xBF/s) {
        print "[NOT OK (Contains BOM)] $filename\n";
        $errors++;
        next;
    }

    # Check if the file contains windows EOL
    if ("$txt" =~ /\r\n/s) {
        print "[NOT OK (Contains Windows EOL)] $filename\n";
        $errors++;
        next;
    }

    # Check if the file contains trailing white spaces
    if ("$txt" =~ / \n/s) {
        print "[NOT OK (Contains trailing white spaces)] $filename\n";
        $errors++;
        next;
    }

    # Check if the file contains tabs
    if ("$txt" =~ /\t/s) {
        print "[NOT OK (Contains tabs)] $filename\n";
        $errors++;
        next;
    }

    # Check if the file contains extra end of lines at EOF
    if ("$txt" =~ /\n\n$/s) {
        print "[NOT OK (Contains extra end of lines at EOF)] $filename\n";
        $errors++;
        next;
    }

    # Check if the file is missing the end of line at EOF
    unless ("$txt" =~ /\n$/s) {
        print "[NOT OK (Does not contains end of lines at EOF)] $filename\n";
        $errors++;
        next;
    }

    # Ensure that scripts are executable on linux
    stat($filename);
    if ("$txt" =~ /^#!.+/s) {
        if ($^O eq "linux") {
            if (! -x _) {
                print "[NOT OK - BSD (script not executable)] $filename\n";
                $errors++;
                next;
            }
        }

    } else {
        if (-x _) {
            print "[NOT OK (executable permission set)] $filename\n";
            $errors++;
            next;
        }
    }

    $ok++;
}

print_if_verbose "\n";
print_if_verbose "---\n";
print_if_verbose "FILES:  $files\n";
print_if_verbose "OK:     $ok\n";
print_if_verbose "SKIP:   $skip\n";
print_if_verbose "KNOWN:  $known\n";
print_if_verbose "ERRORS: $errors\n";
print_if_verbose "---\n";
print_if_verbose "\n";

if ($ok + $skip + $known + $errors != $files) {
    print_if_verbose "[ERROR: Some file was not counted]\n\n";
    exit 1;
}

if ($known < scalar(@skip_files)) {
    print_if_verbose "[ERROR: Some known file was not found and the skip file was not updated]\n\n";
    exit 1;
}

if ($known > scalar(@skip_files)) {
    print_if_verbose "[ERROR: Some new known file was added and the skip file was not updated]\n\n";
    exit 1;
}

if ($errors != 0) {
    print_if_verbose "[ERROR: Some file has a style problem]\n\n";
    exit 1;
}

exit 0;
