::tcltest::configure {*}$::argv

set output_file "output"
set work_dir "work"

# constraint for tests that should only run on Darwin
::tcltest::testConstraint darwin [expr {"@OS_PLATFORM@" eq "darwin"}]

# constraint indicating whether the platform supports trace mode
::tcltest::testConstraint tracemode_support [expr {@TRACEMODE_SUPPORT@ != 0}]

# In-tree test interpreter and source paths
set test_tclsh "@TEST_TCLSH@"
set top_srcdir "@abs_top_srcdir@"

# Set of procs used for testing.

# Sets variables from autoconf for in-tree testing
proc load_variables {pwd} {
    global datadir portsrc cpwd test_tclsh top_srcdir

    set cpwd [file dirname [file dirname $pwd]]

    set datadir "@prefix@/share"
    set portsrc ${cpwd}/test-macports.conf

}

proc cleanup {} {
    global cpwd

    file delete -force /tmp/macports-tests
    file delete -force ${cpwd}/PortIndex ${cpwd}/PortIndex.quick
}

proc without_darwintrace_env {script} {
    set darwintrace_env_vars {
        DYLD_INSERT_LIBRARIES
        DARWINTRACE_LOG
        DARWINTRACE_DEBUG
        DARWINTRACE_UNINITIALIZE
        DARWINTRACE_SPAWN_SETEXEC
        DARWINTRACE_SIP_WORKAROUND_PATH
    }
    set saved_env {}

    foreach var $darwintrace_env_vars {
        if {[info exists ::env($var)]} {
            lappend saved_env $var $::env($var)
            unset ::env($var)
        }
    }

    catch {uplevel 1 $script} result options

    foreach {var value} $saved_env {
        set ::env($var) $value
    }

    return -options $options $result
}

proc with_portsrc {portsrc script} {
    set had_portsrc [info exists ::env(PORTSRC)]
    if {$had_portsrc} {
        set saved_portsrc $::env(PORTSRC)
    }
    set ::env(PORTSRC) $portsrc

    catch {uplevel 1 $script} result options

    if {$had_portsrc} {
        set ::env(PORTSRC) $saved_portsrc
    } else {
        catch {unset ::env(PORTSRC)}
    }

    return -options $options $result
}

# Sets initial directories
proc set_dir {} {
    global datadir cpwd top_srcdir

    cleanup

    file mkdir /tmp/macports-tests/ports \
               /tmp/macports-tests/opt/local/etc/macports \
               /tmp/macports-tests/opt/local/share \
               /tmp/macports-tests/opt/local/var/macports/receipts \
               /tmp/macports-tests/opt/local/var/macports/registry \
               /tmp/macports-tests/opt/local/var/macports/build

    # Populate share/macports from the source tree instead of the prefix
    file mkdir /tmp/macports-tests/opt/local/share/macports/install
    file copy $top_srcdir/macports-pubkey.pem /tmp/macports-tests/opt/local/share/macports/
    file copy $top_srcdir/setupenv.bash /tmp/macports-tests/opt/local/share/macports/
    file copy $top_srcdir/doc/base.mtree /tmp/macports-tests/opt/local/share/macports/install/
    file copy $top_srcdir/doc/prefix.mtree /tmp/macports-tests/opt/local/share/macports/install/
    file copy $top_srcdir/doc/macosx.mtree /tmp/macports-tests/opt/local/share/macports/install/
    file copy $top_srcdir/keys /tmp/macports-tests/opt/local/share/macports/
    file copy ${cpwd}/sources.conf /tmp/macports-tests/opt/local/etc/macports/
    file link -symbolic /tmp/macports-tests/ports/test $cpwd/test
}

# Run portindex
proc port_index {} {
    global cpwd portsrc test_tclsh top_srcdir

    # Move up 2 level to run portindex.
    set path [pwd]
    cd ../..
    # Avoid warning about ports tree being old
    foreach portfile [glob -nocomplain */*/Portfile] {
        file mtime $portfile [clock seconds]
    }

    without_darwintrace_env {
        with_portsrc $portsrc {
            exec -ignorestderr ${test_tclsh} ${top_srcdir}/src/port/portindex.tcl 2>@1
        }
    }

    file copy ${cpwd}/PortIndex ${cpwd}/PortIndex.quick /tmp/macports-tests/ports/

    cd $path
}

# Executes port clean.
proc port_clean {pwd} {
    global portsrc test_tclsh top_srcdir

    set back [pwd]
    cd $pwd

    catch {
        without_darwintrace_env {
            with_portsrc $portsrc {
                exec -ignorestderr ${test_tclsh} ${top_srcdir}/src/port/port.tcl clean 2>@1
            }
        }
    }
    cd $back
}

# Runs the portfile.
proc port_run {pwd} {
    global portsrc test_tclsh top_srcdir

    set back [pwd]
    cd $pwd

    set result [catch {
        without_darwintrace_env {
            with_portsrc $portsrc {
                exec -ignorestderr ${test_tclsh} ${top_srcdir}/src/port/port.tcl -d -N test >&output
            }
        }
    }]
    cd $back
    return $result
}

# Runs port trace.
proc port_trace {pwd} {
    global portsrc test_tclsh top_srcdir

    set back [pwd]
    cd $pwd

    set result [catch {
        with_portsrc $portsrc {
            exec -ignorestderr ${test_tclsh} ${top_srcdir}/src/port/port.tcl -d -N -t test >&output 2>@1
        }
    }]
    cd $back
    return $result
}

# Installs new portfile.
proc port_install {{name "current"}} {
    global portsrc test_tclsh top_srcdir

    set result [catch {
        without_darwintrace_env {
            with_portsrc $portsrc {
                exec -ignorestderr ${test_tclsh} ${top_srcdir}/src/port/port.tcl install $name > output 2>@1
            }
        }
    }]
    return $result
}

# Run configure command.
proc port_config {pwd} {
    global portsrc test_tclsh top_srcdir

    set result [catch {
        without_darwintrace_env {
            with_portsrc $portsrc {
                exec -ignorestderr ${test_tclsh} ${top_srcdir}/src/port/port.tcl configure 2>@1
            }
        }
    }]
    return $result
}

# Run destroot command.
proc port_destroot {pwd} {
    global path portsrc work_dir output_file test_tclsh top_srcdir

    file copy -force ${path}/statefile ${work_dir}/.macports.statefile-unknown-version.state
    if { [exec -ignorestderr id -u] == 0 } {
        exec -ignorestderr chown macports ${work_dir}/.macports.statefile-unknown-version.state
    }
    set result [catch {
        without_darwintrace_env {
            with_portsrc $portsrc {
                exec -ignorestderr ${test_tclsh} ${top_srcdir}/src/port/port.tcl destroot >$output_file 2>@1
            }
        }
    }]
    return $result
}

# Uninstalls portfile.
proc port_uninstall {{name "current"}} {
    global portsrc test_tclsh top_srcdir

    set result [catch {
        without_darwintrace_env {
            with_portsrc $portsrc {
                exec -ignorestderr ${test_tclsh} ${top_srcdir}/src/port/port.tcl uninstall $name > output 2>@1
            }
        }
    }]
    return $result
}

# Returns the line containing a given string
# from a given file, or -1 if nothing is found.
proc get_line {filename lookup} {
    set fp [open $filename r]
    set lookup [string tolower $lookup]

    while {[gets $fp line] != -1} {
        set line [string tolower $line]

        if {[string match $lookup $line] != 0} {
            close $fp
            return $line
        }
    }
    close $fp
    return -1
}

# This proc contains all the steps necessary
# to install a port and save the output to a file.
# Needed for the majority of regression tests.
proc initial_setup {} {
    global output_file work_dir path

    makeFile "" $output_file
    makeDirectory $work_dir

    load_variables $path
    set_dir
    port_index
    port_clean $path
    port_run $path
}
