package claudetool

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

// setupTestFile creates a temporary file with given content for testing
func setupTestFile(t *testing.T, content string) string {
	t.Helper()

	// Create a temporary directory
	tempDir, err := os.MkdirTemp("", "anthropic_edit_test_*")
	if err != nil {
		t.Fatalf("Failed to create temp directory: %v", err)
	}

	// Create a test file in the temp directory
	testFile := filepath.Join(tempDir, "test_file.txt")
	if err := os.WriteFile(testFile, []byte(content), 0o644); err != nil {
		os.RemoveAll(tempDir)
		t.Fatalf("Failed to write test file: %v", err)
	}

	// Register cleanup function
	t.Cleanup(func() {
		os.RemoveAll(tempDir)
	})

	return testFile
}

// callEditTool is a helper to call the edit tool with specific parameters
func callEditTool(t *testing.T, input map[string]any) string {
	t.Helper()

	// Convert input to JSON
	inputJSON, err := json.Marshal(input)
	if err != nil {
		t.Fatalf("Failed to marshal input: %v", err)
	}

	// Call the tool
	result, err := EditRun(context.Background(), inputJSON)
	if err != nil {
		t.Fatalf("Tool execution failed: %v", err)
	}

	return ContentToString(result)
}

// TestEditToolView tests the view command functionality
func TestEditToolView(t *testing.T) {
	content := "Line 1\nLine 2\nLine 3\nLine 4\nLine 5"
	testFile := setupTestFile(t, content)

	// Test the view command
	result := callEditTool(t, map[string]any{
		"command": "view",
		"path":    testFile,
	})

	// Verify results
	if !strings.Contains(result, "Line 1") {
		t.Errorf("View result should contain the file content, got: %s", result)
	}

	// Test view with range
	result = callEditTool(t, map[string]any{
		"command":    "view",
		"path":       testFile,
		"view_range": []int{2, 4},
	})

	// Verify range results
	if strings.Contains(result, "Line 1") || !strings.Contains(result, "Line 2") {
		t.Errorf("View with range should show only specified lines, got: %s", result)
	}
}

// TestEditToolStrReplace tests the str_replace command functionality
func TestEditToolStrReplace(t *testing.T) {
	content := "Line 1\nLine 2\nLine 3\nLine 4\nLine 5"
	testFile := setupTestFile(t, content)

	// Test the str_replace command
	result := callEditTool(t, map[string]any{
		"command": "str_replace",
		"path":    testFile,
		"old_str": "Line 3",
		"new_str": "Modified Line 3",
	})

	// Verify the file was modified
	modifiedContent, err := os.ReadFile(testFile)
	if err != nil {
		t.Fatalf("Failed to read test file: %v", err)
	}

	if !strings.Contains(string(modifiedContent), "Modified Line 3") {
		t.Errorf("File content should be modified, got: %s", string(modifiedContent))
	}

	// Verify the result contains a snippet
	if !strings.Contains(result, "Modified Line 3") {
		t.Errorf("Result should contain the modified content, got: %s", result)
	}
}

// TestEditToolInsert tests the insert command functionality
func TestEditToolInsert(t *testing.T) {
	content := "Line 1\nLine 2\nLine 3\nLine 4\nLine 5"
	testFile := setupTestFile(t, content)

	// Test the insert command
	result := callEditTool(t, map[string]any{
		"command":     "insert",
		"path":        testFile,
		"insert_line": 2,
		"new_str":     "Inserted Line",
	})

	// Verify the file was modified
	modifiedContent, err := os.ReadFile(testFile)
	if err != nil {
		t.Fatalf("Failed to read test file: %v", err)
	}

	expected := "Line 1\nLine 2\nInserted Line\nLine 3\nLine 4\nLine 5"
	if string(modifiedContent) != expected {
		t.Errorf("File content incorrect after insert. Expected:\n%s\nGot:\n%s", expected, string(modifiedContent))
	}

	// Verify the result contains a snippet
	if !strings.Contains(result, "Inserted Line") {
		t.Errorf("Result should contain the inserted content, got: %s", result)
	}
}

// TestEditToolCreate tests the create command functionality
func TestEditToolCreate(t *testing.T) {
	tempDir, err := os.MkdirTemp("", "anthropic_edit_test_create_*")
	if err != nil {
		t.Fatalf("Failed to create temp directory: %v", err)
	}

	t.Cleanup(func() {
		os.RemoveAll(tempDir)
	})

	newFilePath := filepath.Join(tempDir, "new_file.txt")
	content := "This is a new file\nWith multiple lines"

	// Test the create command
	result := callEditTool(t, map[string]any{
		"command":   "create",
		"path":      newFilePath,
		"file_text": content,
	})

	// Verify the file was created with the right content
	createdContent, err := os.ReadFile(newFilePath)
	if err != nil {
		t.Fatalf("Failed to read created file: %v", err)
	}

	if string(createdContent) != content {
		t.Errorf("Created file content incorrect. Expected:\n%s\nGot:\n%s", content, string(createdContent))
	}

	// Verify the result message
	if !strings.Contains(result, "File created successfully") {
		t.Errorf("Result should confirm file creation, got: %s", result)
	}
}

// TestEditToolUndoEdit tests the undo_edit command functionality
func TestEditToolUndoEdit(t *testing.T) {
	originalContent := "Line 1\nLine 2\nLine 3\nLine 4\nLine 5"
	testFile := setupTestFile(t, originalContent)

	// First modify the file
	callEditTool(t, map[string]any{
		"command": "str_replace",
		"path":    testFile,
		"old_str": "Line 3",
		"new_str": "Modified Line 3",
	})

	// Then undo the edit
	result := callEditTool(t, map[string]any{
		"command": "undo_edit",
		"path":    testFile,
	})

	// Verify the file was restored to original content
	restoredContent, err := os.ReadFile(testFile)
	if err != nil {
		t.Fatalf("Failed to read test file: %v", err)
	}

	if string(restoredContent) != originalContent {
		t.Errorf("File content should be restored to original, got: %s", string(restoredContent))
	}

	// Verify the result message
	if !strings.Contains(result, "undone successfully") {
		t.Errorf("Result should confirm undo operation, got: %s", result)
	}
}

// TestEditToolErrors tests various error conditions
func TestEditToolErrors(t *testing.T) {
	content := "Line 1\nLine 2\nLine 3\nLine 4\nLine 5"
	testFile := setupTestFile(t, content)

	testCases := []struct {
		name   string
		input  map[string]any
		errMsg string
	}{
		{
			name: "Invalid command",
			input: map[string]any{
				"command": "invalid_command",
				"path":    testFile,
			},
			errMsg: "unrecognized command",
		},
		{
			name: "Non-existent file",
			input: map[string]any{
				"command": "view",
				"path":    "/non/existent/file.txt",
			},
			errMsg: "does not exist",
		},
		{
			name: "Missing required parameter",
			input: map[string]any{
				"command": "str_replace",
				"path":    testFile,
				// Missing old_str
			},
			errMsg: "parameter old_str is required",
		},
		{
			name: "Multiple occurrences in str_replace",
			input: map[string]any{
				"command": "str_replace",
				"path":    testFile,
				"old_str": "Line", // Appears multiple times
				"new_str": "Modified Line",
			},
			errMsg: "Multiple occurrences",
		},
		{
			name: "Invalid view range",
			input: map[string]any{
				"command":    "view",
				"path":       testFile,
				"view_range": []int{10, 20}, // Out of range
			},
			errMsg: "invalid view_range",
		},
	}

	for _, tc := range testCases {
		t.Run(tc.name, func(t *testing.T) {
			inputJSON, err := json.Marshal(tc.input)
			if err != nil {
				t.Fatalf("Failed to marshal input: %v", err)
			}

			_, err = EditRun(context.Background(), inputJSON)
			if err == nil {
				t.Fatalf("Expected error but got none")
			}

			if !strings.Contains(err.Error(), tc.errMsg) {
				t.Errorf("Error message does not contain expected text. Expected to contain: %q, Got: %q", tc.errMsg, err.Error())
			}
		})
	}
}

// TestHandleStrReplaceEdgeCases tests the handleStrReplace function specifically for edge cases
// that could cause panics like "index out of range [0] with length 0"
func TestHandleStrReplaceEdgeCases(t *testing.T) {
	// The issue was with strings.Split returning an empty slice when the separator wasn't found
	// This test directly tests the internal implementation with conditions that might cause this

	// Create a test file with empty content
	emptyFile := setupTestFile(t, "")

	// Test with empty file content and arbitrary oldStr
	_, err := handleStrReplace(emptyFile, "some string that doesn't exist", "new content")
	if err == nil {
		t.Fatal("Expected error for empty file but got none")
	}
	if !strings.Contains(err.Error(), "did not appear verbatim") {
		t.Errorf("Expected error message to indicate missing string, got: %s", err.Error())
	}

	// Create a file with content that doesn't match oldStr
	nonMatchingFile := setupTestFile(t, "This is some content\nthat doesn't contain the target string")

	// Test with content that doesn't contain oldStr
	_, err = handleStrReplace(nonMatchingFile, "target string not present", "replacement")
	if err == nil {
		t.Fatal("Expected error for non-matching content but got none")
	}
	if !strings.Contains(err.Error(), "did not appear verbatim") {
		t.Errorf("Expected error message to indicate missing string, got: %s", err.Error())
	}

	// Test handling of the edge case that could potentially cause the "index out of range" panic
	// This directly verifies that the handleStrReplace function properly handles the case where
	// strings.Split returns an empty or unexpected result

	// Verify that the protection against empty parts slice works
	fileContent := ""
	oldStr := "some string"
	parts := strings.Split(fileContent, oldStr)
	if len(parts) == 0 {
		// This should match the protection in the code
		parts = []string{""}
	}

	// This should not panic with the fix in place
	_ = strings.Count(parts[0], "\n") // This line would have panicked without the fix
}

// TestViewRangeWithStrReplace tests that the view_range parameter works correctly
// with the str_replace command (tests the full workflow)
func TestViewRangeWithStrReplace(t *testing.T) {
	// Create test file with multiple lines
	content := "Line 1: First line\nLine 2: Second line\nLine 3: Third line\nLine 4: Fourth line\nLine 5: Fifth line"
	testFile := setupTestFile(t, content)

	// First view a subset of the file using view_range
	viewResult := callEditTool(t, map[string]any{
		"command":    "view",
		"path":       testFile,
		"view_range": []int{2, 4}, // Only lines 2-4
	})

	// Verify that we only see the specified lines
	if strings.Contains(viewResult, "Line 1:") || strings.Contains(viewResult, "Line 5:") {
		t.Errorf("View with range should only show lines 2-4, got: %s", viewResult)
	}
	if !strings.Contains(viewResult, "Line 2:") || !strings.Contains(viewResult, "Line 4:") {
		t.Errorf("View with range should show lines 2-4, got: %s", viewResult)
	}

	// Now perform a str_replace on one of the lines we viewed
	replaceResult := callEditTool(t, map[string]any{
		"command": "str_replace",
		"path":    testFile,
		"old_str": "Line 3: Third line",
		"new_str": "Line 3: MODIFIED Third line",
	})

	// Check that the replacement was successful
	if !strings.Contains(replaceResult, "Line 3: MODIFIED Third line") {
		t.Errorf("Replace result should contain the modified line, got: %s", replaceResult)
	}

	// Verify the file content was updated correctly
	modifiedContent, err := os.ReadFile(testFile)
	if err != nil {
		t.Fatalf("Failed to read test file after modification: %v", err)
	}

	expectedContent := "Line 1: First line\nLine 2: Second line\nLine 3: MODIFIED Third line\nLine 4: Fourth line\nLine 5: Fifth line"
	if string(modifiedContent) != expectedContent {
		t.Errorf("File content after replacement is incorrect.\nExpected:\n%s\nGot:\n%s",
			expectedContent, string(modifiedContent))
	}

	// View the modified file with a different view_range
	finalViewResult := callEditTool(t, map[string]any{
		"command":    "view",
		"path":       testFile,
		"view_range": []int{3, 3}, // Only the modified line
	})

	// Verify we can see only the modified line
	if !strings.Contains(finalViewResult, "Line 3: MODIFIED Third line") {
		t.Errorf("Final view should show the modified line, got: %s", finalViewResult)
	}
	if strings.Contains(finalViewResult, "Line 2:") || strings.Contains(finalViewResult, "Line 4:") {
		t.Errorf("Final view should only show line 3, got: %s", finalViewResult)
	}
}
