package tools

import "testing"

func TestWhatWebTool_Name(t *testing.T) {
	if n := NewWhatWebTool().Name(); n != "whatweb" {
		t.Errorf("Name() = %q, want \"whatweb\"", n)
	}
}

func TestWhatWebTool_IsAvailable(t *testing.T) { _ = NewWhatWebTool().IsAvailable() }

// TestParseWhatWebJSON_WithFindings — each detected plugin becomes its
// own "info" finding; version/string evidence is carried through.
func TestParseWhatWebJSON_WithFindings(t *testing.T) {
	input := []byte(`[
		{
			"target": "https://target.example.com",
			"http_status": 200,
			"request_config": {"headers": {"User-Agent": "WhatWeb/0.6.4"}},
			"plugins": {
				"Apache": {"version": ["2.4.7"], "string": ["Apache/2.4.7 (Ubuntu)"]},
				"HTML5": {},
				"HTTPServer": {"os": ["Ubuntu Linux"], "string": ["Apache/2.4.7 (Ubuntu)"]}
			}
		},
		{}
	]`)
	findings := parseWhatWebJSON(input)
	if len(findings) != 3 {
		t.Fatalf("expected 3 findings, got %d", len(findings))
	}
	// Findings are emitted in sorted plugin-name order: Apache, HTML5, HTTPServer.
	apache := findings[0]
	if apache["tool"] != "whatweb" || apache["technology"] != "Apache" {
		t.Errorf("first finding wrong: %+v", apache)
	}
	if apache["severity"] != "info" {
		t.Errorf("severity = %v, want \"info\"", apache["severity"])
	}
	if apache["version"] != "2.4.7" {
		t.Errorf("version not carried through: %+v", apache)
	}
	if apache["title"] != "Apache (2.4.7)" {
		t.Errorf("title wrong: %+v", apache)
	}
	if apache["url"] != "https://target.example.com" || apache["http_status"] != 200 {
		t.Errorf("url/status wrong: %+v", apache)
	}
	html5 := findings[1]
	if html5["technology"] != "HTML5" || html5["title"] != "HTML5" {
		t.Errorf("bare detection wrong: %+v", html5)
	}
	if _, ok := html5["version"]; ok {
		t.Errorf("bare detection should have no version: %+v", html5)
	}
	if findings[2]["os"] != "Ubuntu Linux" {
		t.Errorf("os not carried through: %+v", findings[2])
	}
}

// TestParseWhatWebJSON_EmptyResult — an object with no plugins (or the
// trailing empty object whatweb emits) yields no findings.
func TestParseWhatWebJSON_EmptyResult(t *testing.T) {
	input := []byte(`[
		{"target": "https://target.example.com", "http_status": 200, "plugins": {}},
		{}
	]`)
	if findings := parseWhatWebJSON(input); findings != nil {
		t.Errorf("expected nil findings, got %+v", findings)
	}
}

func TestParseWhatWebJSON_MalformedReturnsNil(t *testing.T) {
	for _, c := range [][]byte{nil, []byte(""), []byte("{not json"), []byte("garbage")} {
		if got := parseWhatWebJSON(c); got != nil {
			t.Errorf("input %q should produce nil, got %v", c, got)
		}
	}
}
