# Tcl launcher script for the project
namespace eval project_launcher {
    # Help information for this script
    proc print_help {} {
        variable script_file "project.tcl"
        puts "\nDescription:"
        puts "Perform actions related to this project.\n"
        puts "Syntax:"
        puts "$script_file"
        puts "$script_file \[action\] \[args\]"
        puts "Usage:"
        puts "Name                   Description"
        puts "-------------------------------------------------------------------------"
        puts "\[action\]             Determine the action to be performed. Default value: help\n"
        puts "                       Current actions: help, clean, sim, verify, test\n"
        puts "\[args\]               Arguments related to the action.\n"
        puts "                       --root 
 changes the root reference for the project.\n"
        puts "-------------------------------------------------------------------------\n"
        exit 0
    }
    proc do_clean { root_dir } {
        variable dir "$root_dir/runs"
        puts "Cleaning all files in directory $dir...\n"
        # Checking if the folder is empty to avoid error
        if {[catch { glob "$dir/*" } result] != 1} {
            file delete -force -- {*}[glob "$dir/*" ]
        }
    }
    proc do_sim_icarus { root_dir verbose } {
        # Checking if the folder is empty to avoid error
        if {[file exists "$root_dir/scripts/run_iverilog.tcl"] == 1} {
            #global root_dir_loc $root_dir
            #source $root_dir/scripts/run_iverilog.tcl
            try {
                set results [exec tclsh $root_dir/scripts/run_iverilog.tcl $root_dir ]
                set status 0
            } trap CHILDSTATUS {results options} {
                set status [lindex [dict get $options -errorcode] 2]
            }
            if {$status != 0} {
                puts "Problem running the script :"
                puts $results
                return
            }
            if {[expr $verbose]} {
                # output the result of the execution
                puts $results
            }
        } else {
            puts "The script run_iverilog.tcl does not exist in $root_dir/scripts"
        }
    }
    proc do_sim_pytest { root_dir verbose } {
        exec pytest $root_dir/tests/ >@stdout 2>@stderr
    }
    proc do_formal { root_dir } {
        # We suppose that the sby file is meant to be run from the inside of the folder
        # hence we cd there
        if {[file pathtype $root_dir] != "absolute"} {
            set root_dir "../$root_dir"
        }
        #set root_dir [file normalize $root_dir]
        cd verification
        #variable fname [glob -nocomplain $root_dir/verification/*.sby]
        variable fname [glob -nocomplain *.sby]
        if {[llength $fname]} {
            set fname [lindex $fname 0]
            puts "Using $fname file..."
            exec sby -f $fname --prefix $root_dir/runs/verification/counter >@stdout 2>@stderr
        } else {
            puts "There are no .sby files present..."
            cd ..
            return
        }
        cd ..
    }
    proc main {} {
        variable root_dir
        # Set the reference directory to where the script is
        #set root_dir [file dirname [info script]]
        # Set the reference directory for source file relative paths (by default the value is script directory path)
        set root_dir "."
        # Use origin directory path location variable, if specified in the tcl shell
        if { [info exists ::root_dir_loc] } {
            set root_dir $::root_dir_loc
        }
        variable action "help"
        variable verbose false
        if { $::argc > 0 } {
            for {set i 0} {$i < $::argc} {incr i} {
                set option [string trim [lindex $::argv $i]]
                switch -regexp -- $option {
                    "--root"   { incr i; set root_dir [lindex $::argv $i] }
                    "--help"         { print_help }
                    "help"         { print_help }
                    "clean"     { set action "clean" }
                    "sim"       {incr i; set action "sim_[lindex $::argv $i]" }
                    "--verbose" { set verbose true }
                    "-v"        { set verbose true }
                    {pytest|cocotb|test}    {set action "pytest"}
                    {formal|verify|verification}  {set action "formal"}
                    default {
                        if { [regexp {^-} $option] } {
                            puts "ERROR: Unknown option '$option' specified, please type '$script_file -tclargs --help' for usage info.\n"
                            return 1
                        }
                    }
                }
            }
        } else {
            print_help
        }
        puts "Script started. The root dir is $root_dir. The action is: $action\n"
        switch -regexp -- $action {
            "clean"   { do_clean $root_dir }
            {sim_icarus|^sim_$|sim_iverilog} { do_sim_icarus $root_dir $verbose}
            {sim_cocotb|pytest} { do_sim_pytest $root_dir $verbose}
            "formal" { do_formal $root_dir}
        }
    }
    main
}