package dockerimg

import (
	"bytes"
	"crypto/rand"
	"crypto/rsa"
	"fmt"
	"io/fs"
	"os"
	"path/filepath"
	"strings"
	"testing"

	"golang.org/x/crypto/ssh"
)

// MockFileSystem implements the FileSystem interface for testing
type MockFileSystem struct {
	Files          map[string][]byte
	CreatedDirs    map[string]bool
	OpenedFiles    map[string]*MockFile
	StatCalledWith []string
	FailOn         map[string]error // Map of function name to error to simulate failures
}

func NewMockFileSystem() *MockFileSystem {
	return &MockFileSystem{
		Files:       make(map[string][]byte),
		CreatedDirs: make(map[string]bool),
		OpenedFiles: make(map[string]*MockFile),
		FailOn:      make(map[string]error),
	}
}

func (m *MockFileSystem) Stat(name string) (fs.FileInfo, error) {
	m.StatCalledWith = append(m.StatCalledWith, name)
	if err, ok := m.FailOn["Stat"]; ok {
		return nil, err
	}

	_, exists := m.Files[name]
	if exists {
		return nil, nil // File exists
	}
	_, exists = m.CreatedDirs[name]
	if exists {
		return nil, nil // Directory exists
	}
	return nil, os.ErrNotExist
}

func (m *MockFileSystem) Mkdir(name string, perm fs.FileMode) error {
	if err, ok := m.FailOn["Mkdir"]; ok {
		return err
	}
	m.CreatedDirs[name] = true
	return nil
}

func (m *MockFileSystem) ReadFile(name string) ([]byte, error) {
	if err, ok := m.FailOn["ReadFile"]; ok {
		return nil, err
	}

	data, exists := m.Files[name]
	if !exists {
		return nil, fmt.Errorf("file not found: %s", name)
	}
	return data, nil
}

func (m *MockFileSystem) WriteFile(name string, data []byte, perm fs.FileMode) error {
	if err, ok := m.FailOn["WriteFile"]; ok {
		return err
	}
	m.Files[name] = data
	return nil
}

// MockFile implements a simple in-memory file for testing
type MockFile struct {
	name     string
	buffer   *bytes.Buffer
	fs       *MockFileSystem
	position int64
}

// MockFileContents represents in-memory file contents for testing
type MockFileContents struct {
	name     string
	contents string
}

func (m *MockFileSystem) OpenFile(name string, flag int, perm fs.FileMode) (*os.File, error) {
	if err, ok := m.FailOn["OpenFile"]; ok {
		return nil, err
	}

	// Initialize the file content if it doesn't exist and we're not in read-only mode
	if _, exists := m.Files[name]; !exists && (flag&os.O_CREATE != 0) {
		m.Files[name] = []byte{}
	}

	data, exists := m.Files[name]
	if !exists {
		return nil, fmt.Errorf("file not found: %s", name)
	}

	// For OpenFile, we'll just use WriteFile to simulate file operations
	// The actual file handle isn't used for much in the sshtheater code
	// but we still need to return a valid file handle
	tmpFile, err := os.CreateTemp("", "mockfile-*")
	if err != nil {
		return nil, err
	}
	if _, err := tmpFile.Write(data); err != nil {
		tmpFile.Close()
		return nil, err
	}
	if _, err := tmpFile.Seek(0, 0); err != nil {
		tmpFile.Close()
		return nil, err
	}

	return tmpFile, nil
}

// MockKeyGenerator implements KeyGenerator interface for testing
type MockKeyGenerator struct {
	privateKey *rsa.PrivateKey
	publicKey  ssh.PublicKey
	FailOn     map[string]error
}

func NewMockKeyGenerator(privateKey *rsa.PrivateKey, publicKey ssh.PublicKey) *MockKeyGenerator {
	return &MockKeyGenerator{
		privateKey: privateKey,
		publicKey:  publicKey,
		FailOn:     make(map[string]error),
	}
}

func (m *MockKeyGenerator) GeneratePrivateKey(bitSize int) (*rsa.PrivateKey, error) {
	if err, ok := m.FailOn["GeneratePrivateKey"]; ok {
		return nil, err
	}
	return m.privateKey, nil
}

func (m *MockKeyGenerator) GeneratePublicKey(privateKey *rsa.PublicKey) (ssh.PublicKey, error) {
	if err, ok := m.FailOn["GeneratePublicKey"]; ok {
		return nil, err
	}
	return m.publicKey, nil
}

// setupMocks sets up common mocks for testing
func setupMocks(t *testing.T) (*MockFileSystem, *MockKeyGenerator, *rsa.PrivateKey) {
	// Generate a real private key using real random
	privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
	if err != nil {
		t.Fatalf("Failed to generate test private key: %v", err)
	}

	// Generate a test public key
	publicKey, err := ssh.NewPublicKey(&privateKey.PublicKey)
	if err != nil {
		t.Fatalf("Failed to generate test public key: %v", err)
	}

	// Create mocks
	mockFS := NewMockFileSystem()
	mockKG := NewMockKeyGenerator(privateKey, publicKey)

	return mockFS, mockKG, privateKey
}

// Helper function to setup a basic SSHTheater for testing
func setupTestSSHTheater(t *testing.T) (*SSHTheater, *MockFileSystem, *MockKeyGenerator) {
	mockFS, mockKG, _ := setupMocks(t)

	// Setup home dir in mock filesystem
	homePath := "/home/testuser"
	sketchDir := filepath.Join(homePath, ".sketch")
	mockFS.CreatedDirs[sketchDir] = true

	// Set HOME environment variable for the test
	oldHome := os.Getenv("HOME")
	os.Setenv("HOME", homePath)
	t.Cleanup(func() { os.Setenv("HOME", oldHome) })

	// Create SSH Theater with mocks
	ssh, err := newSSHTheatherWithDeps("test-container", "localhost", "2222", mockFS, mockKG)
	if err != nil {
		t.Fatalf("Failed to create SSHTheater: %v", err)
	}

	return ssh, mockFS, mockKG
}

func TestNewSSHTheatherCreatesRequiredDirectories(t *testing.T) {
	mockFS, mockKG, _ := setupMocks(t)

	// Set HOME environment variable for the test
	oldHome := os.Getenv("HOME")
	os.Setenv("HOME", "/home/testuser")
	defer func() { os.Setenv("HOME", oldHome) }()

	// Create theater
	_, err := newSSHTheatherWithDeps("test-container", "localhost", "2222", mockFS, mockKG)
	if err != nil {
		t.Fatalf("Failed to create SSHTheater: %v", err)
	}

	// Check if the .sketch directory was created
	expectedDir := "/home/testuser/.sketch"
	if !mockFS.CreatedDirs[expectedDir] {
		t.Errorf("Expected directory %s to be created", expectedDir)
	}
}

func TestCreateKeyPairIfMissing(t *testing.T) {
	ssh, mockFS, _ := setupTestSSHTheater(t)

	// Test key pair creation
	keyPath := "/home/testuser/.sketch/test_key"
	_, err := ssh.createKeyPairIfMissing(keyPath)
	if err != nil {
		t.Fatalf("Failed to create key pair: %v", err)
	}

	// Verify private key file was created
	if _, exists := mockFS.Files[keyPath]; !exists {
		t.Errorf("Private key file not created at %s", keyPath)
	}

	// Verify public key file was created
	pubKeyPath := keyPath + ".pub"
	if _, exists := mockFS.Files[pubKeyPath]; !exists {
		t.Errorf("Public key file not created at %s", pubKeyPath)
	}

	// Verify public key content format
	pubKeyContent, _ := mockFS.ReadFile(pubKeyPath)
	if !bytes.HasPrefix(pubKeyContent, []byte("ssh-rsa ")) {
		t.Errorf("Public key does not have expected format, got: %s", pubKeyContent)
	}
}

// TestAddContainerToSSHConfig tests that the container gets added to the SSH config
// This test uses a direct approach since the OpenFile mocking is complex
func TestAddContainerToSSHConfig(t *testing.T) {
	// Create a temporary directory for test files
	tempDir, err := os.MkdirTemp("", "sshtheater-test-*")
	if err != nil {
		t.Fatalf("Failed to create temp dir: %v", err)
	}
	defer os.RemoveAll(tempDir)

	// Create real files in temp directory
	configPath := filepath.Join(tempDir, "ssh_config")
	initialConfig := `# SSH Config
Host existing-host
  HostName example.com
  User testuser
`
	if err := os.WriteFile(configPath, []byte(initialConfig), 0644); err != nil {
		t.Fatalf("Failed to write initial config: %v", err)
	}

	// Create a theater with the real filesystem but custom paths
	ssh := &SSHTheater{
		cntrName:         "test-container",
		sshHost:          "localhost",
		sshPort:          "2222",
		sshConfigPath:    configPath,
		userIdentityPath: filepath.Join(tempDir, "user_identity"),
		fs:               &RealFileSystem{},
		kg:               &RealKeyGenerator{},
	}

	// Add container to SSH config
	err = ssh.addContainerToSSHConfig()
	if err != nil {
		t.Fatalf("Failed to add container to SSH config: %v", err)
	}

	// Read the updated file
	configData, err := os.ReadFile(configPath)
	if err != nil {
		t.Fatalf("Failed to read updated config: %v", err)
	}
	configStr := string(configData)

	// Check for expected values
	if !strings.Contains(configStr, "Host test-container") {
		t.Errorf("Container host entry not found in config")
	}

	if !strings.Contains(configStr, "HostName localhost") {
		t.Errorf("HostName not correctly added to SSH config")
	}

	if !strings.Contains(configStr, "Port 2222") {
		t.Errorf("Port not correctly added to SSH config")
	}

	if !strings.Contains(configStr, "User root") {
		t.Errorf("User not correctly set to root in SSH config")
	}

	// Check if identity file path is correct
	identityLine := "IdentityFile " + ssh.userIdentityPath
	if !strings.Contains(configStr, identityLine) {
		t.Errorf("Identity file path not correctly added to SSH config")
	}
}

func TestAddContainerToKnownHosts(t *testing.T) {
	// Skip this test as it requires more complex setup
	// The TestSSHTheaterCleanup test covers the addContainerToKnownHosts
	// functionality in a more integrated way
	t.Skip("This test requires more complex setup, integrated test coverage exists in TestSSHTheaterCleanup")
}

func TestRemoveContainerFromSSHConfig(t *testing.T) {
	// Create a temporary directory for test files
	tempDir, err := os.MkdirTemp("", "sshtheater-test-*")
	if err != nil {
		t.Fatalf("Failed to create temp dir: %v", err)
	}
	defer os.RemoveAll(tempDir)

	// Create paths for test files
	sshConfigPath := filepath.Join(tempDir, "ssh_config")
	userIdentityPath := filepath.Join(tempDir, "user_identity")
	knownHostsPath := filepath.Join(tempDir, "known_hosts")

	// Create initial SSH config with container entry
	cntrName := "test-container"
	sshHost := "localhost"
	sshPort := "2222"

	initialConfig := fmt.Sprintf(
		`Host existing-host
  HostName example.com
  User testuser

Host %s
  HostName %s
  User root
  Port %s
  IdentityFile %s
  UserKnownHostsFile %s
`,
		cntrName, sshHost, sshPort, userIdentityPath, knownHostsPath,
	)

	if err := os.WriteFile(sshConfigPath, []byte(initialConfig), 0644); err != nil {
		t.Fatalf("Failed to write initial SSH config: %v", err)
	}

	// Create a theater with the real filesystem but custom paths
	ssh := &SSHTheater{
		cntrName:         cntrName,
		sshHost:          sshHost,
		sshPort:          sshPort,
		sshConfigPath:    sshConfigPath,
		userIdentityPath: userIdentityPath,
		knownHostsPath:   knownHostsPath,
		fs:               &RealFileSystem{},
	}

	// Remove container from SSH config
	err = ssh.removeContainerFromSSHConfig()
	if err != nil {
		t.Fatalf("Failed to remove container from SSH config: %v", err)
	}

	// Read the updated file
	configData, err := os.ReadFile(sshConfigPath)
	if err != nil {
		t.Fatalf("Failed to read updated config: %v", err)
	}
	configStr := string(configData)

	// Check if the container host entry was removed
	if strings.Contains(configStr, "Host "+cntrName) {
		t.Errorf("Container host not removed from SSH config")
	}

	// Check if existing host remains
	if !strings.Contains(configStr, "Host existing-host") {
		t.Errorf("Existing host entry affected by container removal")
	}
}

func TestRemoveContainerFromKnownHosts(t *testing.T) {
	ssh, mockFS, _ := setupTestSSHTheater(t)

	// Setup server public key
	privateKey, _ := ssh.kg.GeneratePrivateKey(2048)
	publicKey, _ := ssh.kg.GeneratePublicKey(&privateKey.PublicKey)
	ssh.serverPublicKey = publicKey

	// Create host line to be removed
	hostLine := "[localhost]:2222 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQ..."
	otherLine := "otherhost ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQ..."

	// Set initial content with the line to be removed
	initialContent := otherLine + "\n" + hostLine
	mockFS.Files[ssh.knownHostsPath] = []byte(initialContent)

	// Add the host to test remove function
	err := ssh.addContainerToKnownHosts()
	if err != nil {
		t.Fatalf("Failed to add container to known_hosts for removal test: %v", err)
	}

	// Now remove it
	err = ssh.removeContainerFromKnownHosts()
	if err != nil {
		t.Fatalf("Failed to remove container from known_hosts: %v", err)
	}

	// Verify content
	updatedContent, _ := mockFS.ReadFile(ssh.knownHostsPath)
	content := string(updatedContent)

	hostPattern := ssh.sshHost + ":" + ssh.sshPort
	if strings.Contains(content, hostPattern) {
		t.Errorf("Container entry not removed from known_hosts")
	}

	// Verify other content remains
	if !strings.Contains(content, otherLine) {
		t.Errorf("Other known_hosts entries improperly removed")
	}
}

func TestSSHTheaterCleanup(t *testing.T) {
	// Create a temporary directory for test files
	tempDir, err := os.MkdirTemp("", "sshtheater-test-*")
	if err != nil {
		t.Fatalf("Failed to create temp dir: %v", err)
	}
	defer os.RemoveAll(tempDir)

	// Create paths for test files
	sshConfigPath := filepath.Join(tempDir, "ssh_config")
	userIdentityPath := filepath.Join(tempDir, "user_identity")
	knownHostsPath := filepath.Join(tempDir, "known_hosts")
	serverIdentityPath := filepath.Join(tempDir, "server_identity")

	// Create private key for server key
	privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
	if err != nil {
		t.Fatalf("Failed to generate private key: %v", err)
	}
	publicKey, err := ssh.NewPublicKey(&privateKey.PublicKey)
	if err != nil {
		t.Fatalf("Failed to generate public key: %v", err)
	}

	// Initialize files
	os.WriteFile(sshConfigPath, []byte("initial ssh_config content"), 0644)
	os.WriteFile(knownHostsPath, []byte("initial known_hosts content"), 0644)

	// Create a theater with the real filesystem but custom paths
	cntrName := "test-container"
	sshHost := "localhost"
	sshPort := "2222"

	ssh := &SSHTheater{
		cntrName:           cntrName,
		sshHost:            sshHost,
		sshPort:            sshPort,
		sshConfigPath:      sshConfigPath,
		userIdentityPath:   userIdentityPath,
		knownHostsPath:     knownHostsPath,
		serverIdentityPath: serverIdentityPath,
		serverPublicKey:    publicKey,
		fs:                 &RealFileSystem{},
		kg:                 &RealKeyGenerator{},
	}

	// Add container to configs
	err = ssh.addContainerToSSHConfig()
	if err != nil {
		t.Fatalf("Failed to set up SSH config for cleanup test: %v", err)
	}

	err = ssh.addContainerToKnownHosts()
	if err != nil {
		t.Fatalf("Failed to set up known_hosts for cleanup test: %v", err)
	}

	// Execute cleanup
	err = ssh.Cleanup()
	if err != nil {
		t.Fatalf("Cleanup failed: %v", err)
	}

	// Read updated files
	configData, err := os.ReadFile(sshConfigPath)
	if err != nil {
		t.Fatalf("Failed to read updated SSH config: %v", err)
	}
	configStr := string(configData)

	// Check container was removed from SSH config
	hostEntry := "Host " + ssh.cntrName
	if strings.Contains(configStr, hostEntry) {
		t.Errorf("Container not removed from SSH config during cleanup")
	}

	// Verify known hosts was updated
	knownHostsContent, err := os.ReadFile(knownHostsPath)
	if err != nil {
		t.Fatalf("Failed to read updated known_hosts: %v", err)
	}

	expectedHostPattern := ssh.sshHost + ":" + ssh.sshPort
	if strings.Contains(string(knownHostsContent), expectedHostPattern) {
		t.Errorf("Container not removed from known_hosts during cleanup")
	}
}

func TestCheckForInclude(t *testing.T) {
	mockFS := NewMockFileSystem()

	// Set HOME environment variable for the test
	oldHome := os.Getenv("HOME")
	os.Setenv("HOME", "/home/testuser")
	defer func() { os.Setenv("HOME", oldHome) }()

	// Create a mock ssh config with the expected include
	includeLine := "Include /home/testuser/.sketch/ssh_config"
	initialConfig := fmt.Sprintf("%s\nHost example\n  HostName example.com\n", includeLine)

	// Add the config to the mock filesystem
	sshConfigPath := "/home/testuser/.ssh/config"
	mockFS.Files[sshConfigPath] = []byte(initialConfig)

	// Test the function with our mock
	err := CheckForIncludeWithFS(mockFS)
	if err != nil {
		t.Fatalf("CheckForInclude failed with proper include: %v", err)
	}

	// Now test with config missing the include
	mockFS.Files[sshConfigPath] = []byte("Host example\n  HostName example.com\n")

	err = CheckForIncludeWithFS(mockFS)
	if err == nil {
		t.Fatalf("CheckForInclude should have returned an error for missing include")
	}
}

func TestSSHTheaterWithErrors(t *testing.T) {
	// Test directory creation failure
	mockFS := NewMockFileSystem()
	mockFS.FailOn["Mkdir"] = fmt.Errorf("mock mkdir error")
	mockKG := NewMockKeyGenerator(nil, nil)

	// Set HOME environment variable for the test
	oldHome := os.Getenv("HOME")
	os.Setenv("HOME", "/home/testuser")
	defer func() { os.Setenv("HOME", oldHome) }()

	// Try to create theater with failing FS
	_, err := newSSHTheatherWithDeps("test-container", "localhost", "2222", mockFS, mockKG)
	if err == nil || !strings.Contains(err.Error(), "mock mkdir error") {
		t.Errorf("Should have failed with mkdir error, got: %v", err)
	}

	// Test key generation failure
	mockFS = NewMockFileSystem()
	mockKG = NewMockKeyGenerator(nil, nil)
	mockKG.FailOn["GeneratePrivateKey"] = fmt.Errorf("mock key generation error")

	_, err = newSSHTheatherWithDeps("test-container", "localhost", "2222", mockFS, mockKG)
	if err == nil || !strings.Contains(err.Error(), "key generation error") {
		t.Errorf("Should have failed with key generation error, got: %v", err)
	}
}

func TestRealSSHTheatherInit(t *testing.T) {
	// This is a basic smoke test for the real NewSSHTheather method
	// We'll mock the os.Getenv("HOME") but use real dependencies otherwise

	// Create a temp dir to use as HOME
	tempDir, err := os.MkdirTemp("", "sshtheater-test-home-*")
	if err != nil {
		t.Fatalf("Failed to create temp dir: %v", err)
	}
	defer os.RemoveAll(tempDir)

	// Set HOME environment for the test
	oldHome := os.Getenv("HOME")
	os.Setenv("HOME", tempDir)
	defer os.Setenv("HOME", oldHome)

	// Create the theater
	theater, err := NewSSHTheather("test-container", "localhost", "2222")
	if err != nil {
		t.Fatalf("Failed to create real SSHTheather: %v", err)
	}

	// Just some basic checks
	if theater == nil {
		t.Fatal("Theater is nil")
	}

	// Check if the sketch dir was created
	sketchDir := filepath.Join(tempDir, ".sketch")
	if _, err := os.Stat(sketchDir); os.IsNotExist(err) {
		t.Errorf(".sketch directory not created")
	}

	// Check if key files were created
	if _, err := os.Stat(theater.serverIdentityPath); os.IsNotExist(err) {
		t.Errorf("Server identity file not created")
	}

	if _, err := os.Stat(theater.userIdentityPath); os.IsNotExist(err) {
		t.Errorf("User identity file not created")
	}

	// Check if the config files were created
	if _, err := os.Stat(theater.sshConfigPath); os.IsNotExist(err) {
		t.Errorf("SSH config file not created")
	}

	if _, err := os.Stat(theater.knownHostsPath); os.IsNotExist(err) {
		t.Errorf("Known hosts file not created")
	}

	// Clean up
	err = theater.Cleanup()
	if err != nil {
		t.Fatalf("Failed to clean up theater: %v", err)
	}
}
