# Copyright 2020-2022 Free Software Foundation, Inc.

# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

# Helper functions to make it easier to write debuginfod tests.

# Return true if the debuginfod tests should be skipped, otherwise, return
# false.
proc skip_debuginfod_tests {} {
    if [is_remote host] {
	return true
    }

    if { [which debuginfod] == 0 } {
	return true
    }

    if { [which curl] == 0 } {
	untested "cannot find curl"
	return true
    }

    # Skip testing if gdb was not configured with debuginfod.
    #
    # If GDB is built with ASan, it warns that some signal handlers
    # (installed by ASan) exist on startup.  That makes TCL's exec throw an
    # error.  Disable that by passing --quiet.
    if { [string first "with-debuginfod" \
	      [eval exec $::GDB --quiet $::INTERNAL_GDBFLAGS \
		   --configuration]] == -1 } {
	return true
    }

    return false
}

# Create two directories within the current output directory.  One directory
# will be used by GDB as the client cache to hold downloaded debug
# information, and the other directory will be used by the debuginfod server
# as its cache of the parsed debug files that will be served to GDB.
#
# Call this proc with the names to two variables, these variables will be
# set in the parent scope with the paths to the two directories.
#
# This proc allocates the names for the directories, but doesn't create
# them.  In fact, if the directories already exist, this proc will delete
# them, this ensures that any existing contents are also deleted.
proc prepare_for_debuginfod { cache_var db_var } {
    upvar $cache_var cache
    upvar $db_var db

    set cache [standard_output_file ".client_cache"]
    set db [standard_output_file ".debuginfod.db"]

    # Delete any preexisting test files.
    file delete -force $cache
    file delete -force $db
}

# Run BODY with the three environment variables required to control
# debuginfod set.  The timeout is set based on the usual timeouts used by
# GDB within dejagnu (see get_largest_timeout), the debuginfod cache is set
# to CACHE (this is where downloaded debug data is placed), and the
# debuginfod urls environment variable is set to be the empty string.
#
# Within BODY you should start a debuginfod server and set the environment
# variable DEBUGINFOD_URLS as appropriate (see start_debuginfod for details).
#
# The reason that this proc doesn't automatically start debuginfod, is that
# in some test cases we want to initially test with debuginfod not running
# and/or disabled.
proc with_debuginfod_env { cache body } {
    set envlist \
	[list \
	     env(DEBUGINFOD_URLS) \
	     env(DEBUGINFOD_TIMEOUT) \
	     env(DEBUGINFOD_CACHE_PATH)]

    save_vars $envlist {
	setenv DEBUGINFOD_TIMEOUT [get_largest_timeout]
	setenv DEBUGINFOD_CACHE_PATH $cache
	setenv DEBUGINFOD_URLS ""

	uplevel 1 $body
    }
}

# Start a debuginfod server.  DB is the directory to use for the server's
# database cache, while DEBUGDIR is a directory containing all the debug
# information that the server should server.
#
# This proc will try to find an available port to start the server on, will
# start the server, and check that the server has started correctly.
#
# If the server starts correctly, then this proc will return the url that
# should be used to communicate with the server.  If the server can't be
# started, then an error will be printed, and an empty string returned.
#
# If the server is successfully started then the global variable
# debuginfod_spawn_id will be set with the spawn_id of the debuginfod
# process.
proc start_debuginfod { db debugdir } {
    global debuginfod_spawn_id spawn_id

    # Find an unused port.
    set port 7999
    set found false
    while { ! $found } {
	incr port
	if { $port == 65536 } {
	    perror "no available ports"
	    return ""
	}

	if { [info exists spawn_id] } {
	    set old_spawn_id $spawn_id
	}

	spawn debuginfod -vvvv -d $db -p $port -F $debugdir
	set debuginfod_spawn_id $spawn_id

	if { [info exists old_spawn_id] } {
	    set spawn_id $old_spawn_id
	    unset old_spawn_id
	}

	expect {
	    -i $debuginfod_spawn_id
	    "started http server on IPv4 IPv6 port=$port" { set found true }
	    "started http server on IPv4 port=$port" { set found true }
	    "started http server on IPv6 port=$port" {}
	    "failed to bind to port" {}
	    timeout {
		stop_debuginfod
		perror "find port timeout"
		return ""
	    }
	}
	if { ! $found } {
	    stop_debuginfod
	}
    }

    set url "http://127.0.0.1:$port"

    set metrics [list "ready 1" \
		     "thread_work_total{role=\"traverse\"} 1" \
		     "thread_work_pending{role=\"scan\"} 0" \
		     "thread_busy{role=\"scan\"} 0"]

    # Check server metrics to confirm init has completed.
    foreach m $metrics {
	set timelim 20
	while { $timelim != 0 } {
	    sleep 0.5
	    catch {exec curl -s $url/metrics} got

	    if { [regexp $m $got] } {
		break
	    }

	    incr timelim -1
	}

	if { $timelim == 0 } {
	    stop_debuginfod
	    perror "server init timeout"
	    return ""
	}
    }

    return $url
}

# If the global debuginfod_spawn_id exists, then kill that process and unset
# the debuginfod_spawn_id global.  This can be used to shutdown the
# debuginfod server.
proc stop_debuginfod { } {
    global debuginfod_spawn_id

    if [info exists debuginfod_spawn_id] {
	kill_wait_spawned_process $debuginfod_spawn_id
	unset debuginfod_spawn_id
    }
}
