// Copyright 2026 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package main

import (
	"encoding/json"
	"fmt"
	"os"
	"path/filepath"
	"reflect"
	"strings"
	"testing"
)

func TestSplitCommand(t *testing.T) {
	tests := []struct {
		cmd      string
		expected []string
	}{
		{
			cmd:      "clang++ -o obj/file.o -c file.cc",
			expected: []string{"clang++", "-o", "obj/file.o", "-c", "file.cc"},
		},
		{
			cmd:      `clang++ "-DQUOTED_ARG" -o "obj/path with spaces.o"`,
			expected: []string{"clang++", "-DQUOTED_ARG", "-o", "obj/path with spaces.o"},
		},
		{
			cmd:      `clang++ 'single quoted' -DFOO=\"bar\"`,
			expected: []string{"clang++", "single quoted", "-DFOO=\"bar\""},
		},
		{
			cmd:      "arg1\\ with\\ space arg2",
			expected: []string{"arg1 with space", "arg2"},
		},
	}

	for _, test := range tests {
		result := splitCommand(test.cmd)
		if !reflect.DeepEqual(result, test.expected) {
			t.Errorf("splitCommand(%q) = %v; want %v", test.cmd, result, test.expected)
		}
	}
}

func TestExtractOutput(t *testing.T) {
	tests := []struct {
		cmd      CompileCommand
		expected string
	}{
		{
			cmd: CompileCommand{
				Directory: "/build",
				Arguments: []string{"clang++", "-o", "out.o", "in.cc"},
			},
			expected: "/build/out.o",
		},
		{
			cmd: CompileCommand{
				Directory: "/build",
				Command:   "clang++ -o /abs/out.o in.cc",
			},
			expected: "/abs/out.o",
		},
	}

	for _, test := range tests {
		result, err := ExtractOutput(test.cmd)
		if err != nil {
			t.Errorf("ExtractOutput failed: %v", err)
		}
		if result != test.expected {
			t.Errorf("ExtractOutput = %q; want %q", result, test.expected)
		}
	}
}

func TestPopulateTargets(t *testing.T) {
	// Create a temporary business logic context.
	tmpDir, err := os.MkdirTemp("", "ide-query-test")
	if err != nil {
		t.Fatal(err)
	}
	defer os.RemoveAll(tmpDir)

	fuchsiaDir := filepath.Join(tmpDir, "fuchsia")
	buildDir := filepath.Join(fuchsiaDir, "out/default")
	os.MkdirAll(buildDir, 0755)

	sourceFile := filepath.Join(fuchsiaDir, "src/main.cc")
	os.MkdirAll(filepath.Dir(sourceFile), 0755)
	os.WriteFile(sourceFile, []byte("void main() {}"), 0644)

	// Create a mock compile_commands.json
	compDb := []CompileCommand{
		{
			Directory: buildDir,
			File:      "../../src/main.cc",
			Arguments: []string{"clang++", "-o", "obj/main.o", "-c", "../../src/main.cc"},
		},
	}
	dbContent, _ := json.Marshal(compDb)
	os.WriteFile(filepath.Join(buildDir, "compile_commands.json"), dbContent, 0644)

	// Mock the Build API resolver.
	oldResolve := resolveNinjaPath
	defer func() { resolveNinjaPath = oldResolve }()
	resolveNinjaPath = func(ctx *WorkspaceContext, ninjaPath string) (string, error) {
		if ninjaPath == "obj/main.o" {
			return "//src:main_target", nil
		}
		return "", nil
	}

	ctx := &WorkspaceContext{
		FuchsiaDir: fuchsiaDir,
		BuildDir:   buildDir,
		Files: []FileEntry{
			{
				AbsPath: sourceFile,
				Status:  StatusFound,
			},
		},
	}

	if err := ctx.PopulateTargets(); err != nil {
		t.Fatalf("PopulateTargets failed: %v", err)
	}

	if len(ctx.Files[0].BuildTargets) != 1 || ctx.Files[0].BuildTargets[0] != "//src:main_target" {
		t.Errorf("expected //src:main_target, got %v", ctx.Files[0].BuildTargets)
	}
}

func TestPopulateTargets_NestedHeader(t *testing.T) {
	tmpDir, err := os.MkdirTemp("", "ide-query-test-nested")
	if err != nil {
		t.Fatal(err)
	}
	defer os.RemoveAll(tmpDir)

	fuchsiaDir := filepath.Join(tmpDir, "fuchsia")
	buildDir := filepath.Join(fuchsiaDir, "out/default")
	os.MkdirAll(buildDir, 0755)

	sourceFile := filepath.Join(fuchsiaDir, "zircon/kernel/lib/arch/x86/standard-segments.cc")
	headerFile := filepath.Join(fuchsiaDir, "zircon/kernel/lib/arch/x86/include/lib/arch/x86/standard-segments.h")
	os.MkdirAll(filepath.Dir(sourceFile), 0755)
	os.MkdirAll(filepath.Dir(headerFile), 0755)
	os.WriteFile(sourceFile, []byte("void f() {}"), 0644)
	os.WriteFile(headerFile, []byte("void f();"), 0644)

	compDb := []CompileCommand{
		{
			Directory: buildDir,
			File:      "../../zircon/kernel/lib/arch/x86/standard-segments.cc",
			Arguments: []string{"clang++", "-o", "obj/zircon/kernel/lib/arch/x86/standard-segments.o", "-c", "../../zircon/kernel/lib/arch/x86/standard-segments.cc"},
		},
	}
	dbContent, _ := json.Marshal(compDb)
	os.WriteFile(filepath.Join(buildDir, "compile_commands.json"), dbContent, 0644)

	oldResolve := resolveNinjaPath
	defer func() { resolveNinjaPath = oldResolve }()
	resolveNinjaPath = func(ctx *WorkspaceContext, ninjaPath string) (string, error) {
		if ninjaPath == "obj/zircon/kernel/lib/arch/x86/standard-segments.o" {
			return "//zircon/kernel/lib/arch/x86:x86", nil
		}
		return "", nil
	}

	ctx := &WorkspaceContext{
		FuchsiaDir: fuchsiaDir,
		BuildDir:   buildDir,
		Files: []FileEntry{
			{
				AbsPath: headerFile,
				Status:  StatusFound,
			},
		},
	}

	if err := ctx.PopulateTargets(); err != nil {
		t.Fatalf("PopulateTargets failed: %v", err)
	}

	if len(ctx.Files[0].BuildTargets) != 1 || ctx.Files[0].BuildTargets[0] != "//zircon/kernel/lib/arch/x86:x86" {
		t.Errorf("expected //zircon/kernel/lib/arch/x86:x86, got %v", ctx.Files[0].BuildTargets)
	}
}
func TestVerifyBuild_NoArgsGn(t *testing.T) {
	tmpDir := t.TempDir()
	fuchsiaDir := filepath.Join(tmpDir, "fuchsia")
	buildDir := filepath.Join(fuchsiaDir, "out/default")
	os.MkdirAll(buildDir, 0755)

	ctx := &WorkspaceContext{
		FuchsiaDir: fuchsiaDir,
		BuildDir:   buildDir,
		Files: []FileEntry{
			{AbsPath: filepath.Join(fuchsiaDir, "src/main.cc"), Status: StatusFound},
		},
	}

	if err := ctx.VerifyBuild(); err != nil {
		t.Fatalf("VerifyBuild failed: %v", err)
	}

	if !strings.Contains(ctx.Files[0].AnalysisError, "args.gn missing") {
		t.Errorf("expected AnalysisError about missing args.gn, got %q", ctx.Files[0].AnalysisError)
	}
}

func TestVerifyBuild_Success(t *testing.T) {
	tmpDir := t.TempDir()
	fuchsiaDir := filepath.Join(tmpDir, "fuchsia")
	buildDir := filepath.Join(fuchsiaDir, "out/default")
	os.MkdirAll(buildDir, 0755)
	os.WriteFile(filepath.Join(buildDir, "args.gn"), []byte("foo=bar"), 0644)

	// Mock runFx
	oldRunFx := runFx
	defer func() { runFx = oldRunFx }()
	runFxCalled := false
	runFx = func(ctx *WorkspaceContext, dir string, args ...string) error {
		if args[0] == "build" {
			runFxCalled = true
		}
		return nil
	}

	ctx := &WorkspaceContext{
		FuchsiaDir: fuchsiaDir,
		BuildDir:   buildDir,
		Files: []FileEntry{
			{
				AbsPath:      filepath.Join(fuchsiaDir, "src/main.cc"),
				Status:       StatusFound,
				BuildTargets: []string{"//src:main"},
			},
		},
	}

	if err := ctx.VerifyBuild(); err != nil {
		t.Fatalf("VerifyBuild failed: %v", err)
	}

	if !runFxCalled {
		t.Error("expected runFx to be called for build")
	}

	if ctx.Files[0].AnalysisResult == nil || ctx.Files[0].AnalysisResult.Status != AnalysisStatusOk {
		t.Errorf("expected AnalysisStatusOk, got %+v", ctx.Files[0].AnalysisResult)
	}
}

func TestVerifyBuild_Failure(t *testing.T) {
	tmpDir := t.TempDir()
	fuchsiaDir := filepath.Join(tmpDir, "fuchsia")
	buildDir := filepath.Join(fuchsiaDir, "out/default")
	os.MkdirAll(buildDir, 0755)
	os.WriteFile(filepath.Join(buildDir, "args.gn"), []byte("foo=bar"), 0644)

	// Mock runFx to fail on build
	oldRunFx := runFx
	defer func() { runFx = oldRunFx }()
	runFx = func(ctx *WorkspaceContext, dir string, args ...string) error {
		if args[0] == "build" {
			return fmt.Errorf("build failed")
		}
		return nil
	}

	ctx := &WorkspaceContext{
		FuchsiaDir: fuchsiaDir,
		BuildDir:   buildDir,
		Files: []FileEntry{
			{
				AbsPath:      filepath.Join(fuchsiaDir, "src/main.cc"),
				Status:       StatusFound,
				BuildTargets: []string{"//src:main"},
			},
		},
	}

	if err := ctx.VerifyBuild(); err != nil {
		t.Fatalf("VerifyBuild failed: %v", err)
	}

	if ctx.Files[0].AnalysisResult == nil || ctx.Files[0].AnalysisResult.Status != AnalysisStatusBuildFailed {
		t.Errorf("expected AnalysisStatusBuildFailed, got %+v", ctx.Files[0].AnalysisResult)
	}
	if ctx.Files[0].AnalysisResult.Message != "File failed to build." {
		t.Errorf("expected 'File failed to build.', got %q", ctx.Files[0].AnalysisResult.Message)
	}
}

func TestVerifyBuild_GenFailure(t *testing.T) {
	tmpDir := t.TempDir()
	fuchsiaDir := filepath.Join(tmpDir, "fuchsia")
	buildDir := filepath.Join(fuchsiaDir, "out/default")
	os.MkdirAll(buildDir, 0755)
	os.WriteFile(filepath.Join(buildDir, "args.gn"), []byte("foo=bar"), 0644)

	// Mock runFx to fail on gen
	oldRunFx := runFx
	defer func() { runFx = oldRunFx }()
	runFx = func(ctx *WorkspaceContext, dir string, args ...string) error {
		if args[0] == "gen" {
			return fmt.Errorf("gen failed")
		}
		return nil
	}

	ctx := &WorkspaceContext{
		FuchsiaDir: fuchsiaDir,
		BuildDir:   buildDir,
		Files: []FileEntry{
			{
				AbsPath: filepath.Join(fuchsiaDir, "src/main.cc"),
				Status:  StatusFound,
			},
		},
	}

	if err := ctx.VerifyBuild(); err != nil {
		t.Fatalf("VerifyBuild failed: %v", err)
	}

	if !strings.Contains(ctx.Files[0].AnalysisError, "fx gen failed") {
		t.Errorf("expected AnalysisError about fx gen failure, got %q", ctx.Files[0].AnalysisError)
	}
}

func TestVerifyBuild_SyncFailure(t *testing.T) {
	tmpDir := t.TempDir()
	fuchsiaDir := filepath.Join(tmpDir, "fuchsia")
	buildDir := filepath.Join(fuchsiaDir, "out/default")
	os.MkdirAll(buildDir, 0755)
	os.WriteFile(filepath.Join(buildDir, "args.gn"), []byte("foo=bar"), 0644)

	// Create a file where ide-analysis/args.gn should go, and make it a directory to cause WriteFile to fail.
	ideAnalysisDir := filepath.Join(fuchsiaDir, "out", ".ide-analysis")
	os.MkdirAll(filepath.Join(ideAnalysisDir, "args.gn"), 0755)

	ctx := &WorkspaceContext{
		FuchsiaDir: fuchsiaDir,
		BuildDir:   buildDir,
		Files: []FileEntry{
			{
				AbsPath: filepath.Join(fuchsiaDir, "src/main.cc"),
				Status:  StatusFound,
			},
		},
	}

	if err := ctx.VerifyBuild(); err != nil {
		t.Fatalf("VerifyBuild failed: %v", err)
	}

	if !strings.Contains(ctx.Files[0].AnalysisError, "failed to sync args.gn") {
		t.Errorf("expected AnalysisError about sync failure, got %q", ctx.Files[0].AnalysisError)
	}
}

func TestPopulateTargets_DeterministicNeighbor(t *testing.T) {
	tmpDir, err := os.MkdirTemp("", "ide-query-test-determinism")
	if err != nil {
		t.Fatal(err)
	}
	defer os.RemoveAll(tmpDir)

	fuchsiaDir := filepath.Join(tmpDir, "fuchsia")
	buildDir := filepath.Join(fuchsiaDir, "out/default")
	os.MkdirAll(buildDir, 0755)

	fileA := filepath.Join(fuchsiaDir, "src/a.cc")
	fileB := filepath.Join(fuchsiaDir, "src/b.cc")
	headerFile := filepath.Join(fuchsiaDir, "src/header.h")
	os.MkdirAll(filepath.Dir(fileA), 0755)
	os.WriteFile(fileA, []byte(""), 0644)
	os.WriteFile(fileB, []byte(""), 0644)
	os.WriteFile(headerFile, []byte(""), 0644)

	// In the compdb, A comes before B.
	// dirToCmd["src"] should be A's command.
	compDb := []CompileCommand{
		{
			Directory: buildDir,
			File:      "../../src/a.cc",
			Arguments: []string{"clang++", "-o", "obj/a.o", "-c", "../../src/a.cc"},
		},
		{
			Directory: buildDir,
			File:      "../../src/b.cc",
			Arguments: []string{"clang++", "-o", "obj/b.o", "-c", "../../src/b.cc"},
		},
	}
	dbContent, _ := json.Marshal(compDb)
	os.WriteFile(filepath.Join(buildDir, "compile_commands.json"), dbContent, 0644)

	oldResolve := resolveNinjaPath
	defer func() { resolveNinjaPath = oldResolve }()
	resolveNinjaPath = func(ctx *WorkspaceContext, ninjaPath string) (string, error) {
		if ninjaPath == "obj/a.o" {
			return "//src:a", nil
		}
		if ninjaPath == "obj/b.o" {
			return "//src:b", nil
		}
		return "", nil
	}

	ctx := &WorkspaceContext{
		FuchsiaDir: fuchsiaDir,
		BuildDir:   buildDir,
		Files: []FileEntry{
			{
				AbsPath: headerFile,
				Status:  StatusFound,
			},
		},
	}

	if err := ctx.PopulateTargets(); err != nil {
		t.Fatalf("PopulateTargets failed: %v", err)
	}

	// Should favor the first one in the list (//src:a) because we only
	// set the dirToCmd map if it's not already present.
	if len(ctx.Files[0].BuildTargets) != 1 || ctx.Files[0].BuildTargets[0] != "//src:a" {
		t.Errorf("expected //src:a, got %v", ctx.Files[0].BuildTargets)
	}
}

func TestPopulateTargets_MultipleTargets(t *testing.T) {
	tmpDir, err := os.MkdirTemp("", "ide-query-test-multi")
	if err != nil {
		t.Fatal(err)
	}
	defer os.RemoveAll(tmpDir)

	fuchsiaDir := filepath.Join(tmpDir, "fuchsia")
	buildDir := filepath.Join(fuchsiaDir, "out/default")
	os.MkdirAll(buildDir, 0755)

	sourceFile := filepath.Join(fuchsiaDir, "src/main.cc")
	os.MkdirAll(filepath.Dir(sourceFile), 0755)
	os.WriteFile(sourceFile, []byte(""), 0644)

	// Create a mock compile_commands.json with TWO entries for the same file.
	compDb := []CompileCommand{
		{
			Directory: buildDir,
			File:      "../../src/main.cc",
			Arguments: []string{"clang++", "-o", "obj/foo.o", "-c", "../../src/main.cc"},
		},
		{
			Directory: buildDir,
			File:      "../../src/main.cc",
			Arguments: []string{"clang++", "-o", "obj/bar.o", "-c", "../../src/main.cc"},
		},
	}
	dbContent, _ := json.Marshal(compDb)
	os.WriteFile(filepath.Join(buildDir, "compile_commands.json"), dbContent, 0644)

	oldResolve := resolveNinjaPath
	defer func() { resolveNinjaPath = oldResolve }()
	resolveNinjaPath = func(ctx *WorkspaceContext, ninjaPath string) (string, error) {
		if ninjaPath == "obj/foo.o" {
			return "//src:foo", nil
		}
		if ninjaPath == "obj/bar.o" {
			return "//src:bar", nil
		}
		return "", nil
	}

	ctx := &WorkspaceContext{
		FuchsiaDir: fuchsiaDir,
		BuildDir:   buildDir,
		Files: []FileEntry{
			{
				AbsPath: sourceFile,
				Status:  StatusFound,
			},
		},
	}

	if err := ctx.PopulateTargets(); err != nil {
		t.Fatalf("PopulateTargets failed: %v", err)
	}

	// Should pick //src:bar because it's alphabetically before //src:foo
	if len(ctx.Files[0].BuildTargets) != 1 || ctx.Files[0].BuildTargets[0] != "//src:bar" {
		t.Errorf("expected //src:bar, got %v", ctx.Files[0].BuildTargets)
	}
}
