package config_test

import (
	"strings"
	"testing"

	"github.com/vulncheck-oss/go-exploit/c2"
	"github.com/vulncheck-oss/go-exploit/config"
)

func TestDefaultFlags(t *testing.T) {
	conf := config.NewRemoteExploit(
		config.ImplementedFeatures{AssetDetection: true, VersionScanning: true, Exploitation: true},
		config.CodeExecution, []c2.Impl{}, "Apache", []string{"OFBiz"},
		[]string{"cpe:2.3:a:apache:ofbiz"}, "CVE-2024-45507", "HTTP", 80)

	conf.CreateStringFlag("teststring1", "default!", "string usage")
	conf.CreateUintFlag("testuint1", 99, "uint usage")
	conf.CreateIntFlag("testint1", 300, "int usage")
	conf.CreateBoolFlag("testbool1", true, "bool usage")

	if conf.GetStringFlag("teststring1") != "default!" {
		t.Error("Unexpected GetStringFlag results")
	}
	if conf.GetStringFlag("wat") != "" {
		t.Error("Failed string lookup should default to empty string")
	}
	if conf.GetUintFlag("teststring1") != 0 {
		t.Error("Failed uint lookup should default to 0")
	}
	if conf.GetUintFlag("testuint1") != 99 {
		t.Error("Unexpected GetUintFlag results")
	}
	if conf.GetIntFlag("testint1") != 300 {
		t.Error("Unexpected GetIntFlag results")
	}
	if !conf.GetBoolFlag("testbool1") {
		t.Error("Unexpected GetBoolFlag results")
	}
}

func TestExternalDefaultFlags(t *testing.T) {
	conf := config.NewRemoteExploit(
		config.ImplementedFeatures{AssetDetection: true, VersionScanning: true, Exploitation: true},
		config.CodeExecution, []c2.Impl{}, "Apache", []string{"OFBiz"},
		[]string{"cpe:2.3:a:apache:ofbiz"}, "CVE-2024-45507", "HTTP", 80)

	testString := "test"
	conf.CreateStringVarFlag(&testString, "teststring", "default!", "string usage")
	testUInt := uint(88)
	conf.CreateUintVarFlag(&testUInt, "testuint", 99, "uint usage")
	testInt := -88
	conf.CreateIntVarFlag(&testInt, "testint", 300, "int usage")
	testBool := true
	conf.CreateBoolVarFlag(&testBool, "testbool", true, "bool usage")

	if conf.GetStringFlag("teststring") != "default!" {
		t.Error("Unexpected GetStringFlag results")
	}
	if conf.GetStringFlag("wat") != "" {
		t.Error("Failed string lookup should default to empty string")
	}
	if conf.GetUintFlag("teststring") != 0 {
		t.Error("Failed uint lookup should default to 0")
	}
	if conf.GetUintFlag("testuint") != 99 {
		t.Error("Unexpected GetUintFlag results")
	}
	if conf.GetIntFlag("testint") != 300 {
		t.Error("Unexpected GetIntFlag results")
	}
	if !conf.GetBoolFlag("testbool") {
		t.Error("Unexpected GetBoolFlag results")
	}
}

func TestApplyTemplate(t *testing.T) {
	conf := config.NewRemoteExploit(
		config.ImplementedFeatures{AssetDetection: true, VersionScanning: true, Exploitation: true},
		config.CodeExecution, []c2.Impl{}, "Apache", []string{"OFBiz"},
		[]string{"cpe:2.3:a:apache:ofbiz"}, "CVE-2024-45507", "HTTP", 80)

	conf.CreateStringFlag("teststring2", "default!", "string usage")
	conf.CreateUintFlag("testuint2", 99, "uint usage")
	conf.CreateIntFlag("testint2", 300, "int usage")
	conf.CreateBoolFlag("testbool2", true, "bool usage")

	s := conf.ApplyTemplate("{{.CVE}} {{.StringFlagsMap.teststring2}} {{.UintFlagsMap.testuint2}} {{.IntFlagsMap.testint2}} {{.BoolFlagsMap.testbool2}}")
	if s == "" {
		t.Error("Template returned error")
	}
	s = conf.ApplyTemplate("{{.CVE}} {{.StringFlagsMap.teststring2}} {{.UintFlagsMap.testuint2}} {{.IntFlagsMap.testint2}} {{.BoolFlagsMap.testbool2}}")
	if s == "" {
		t.Error("Template returned error")
	}

	if s != "CVE-2024-45507 default! 99 300 true" {
		t.Errorf("'%s' unexpected", s)
	}
}

func TestGenerateURL(t *testing.T) {
	conf := config.NewRemoteExploit(
		config.ImplementedFeatures{AssetDetection: true, VersionScanning: true, Exploitation: true},
		config.CodeExecution, []c2.Impl{}, "Apache", []string{"OFBiz"},
		[]string{"cpe:2.3:a:apache:ofbiz"}, "CVE-2024-45507", "HTTP", 80)
	conf.Rhost = "127.13.37.1"
	conf.Rport = 31337
	conf.SSL = true

	if strings.Compare(conf.GenerateURL("/vulncheck"), `https://127.13.37.1:31337/vulncheck`) != 0 {
		t.Errorf("GenerateURL did not generate expected HTTPS URL: `%s` != `%s`", conf.GenerateURL("/vulncheck"), `https://127.13.37.1:31337/vulncheck`)
	}
	conf.SSL = false
	if strings.Compare(conf.GenerateURL("/vulncheck"), `http://127.13.37.1:31337/vulncheck`) != 0 {
		t.Errorf("GenerateURL did not generate expected HTTP URL: `%s` != `%s`", conf.GenerateURL("/vulncheck"), `http://127.13.37.1:31337/vulncheck`)
	}
}
