package daemon

import (
	"errors"
	"os"
	"path/filepath"
	"runtime"
	"testing"

	"github.com/tidbcloud/AgentTeam/desktop/internal/profile"
)

func TestInstanceLockAcquireBusyReleaseAndReacquire(t *testing.T) {
	configDir := t.TempDir()
	t.Setenv(profile.ConfigDirEnvKey, configDir)

	var nilLock *InstanceLock
	if err := nilLock.Release(); err != nil {
		t.Fatalf("nil Release() error = %v", err)
	}

	first, err := AcquireInstanceLock()
	if err != nil {
		t.Fatalf("first AcquireInstanceLock() error = %v", err)
	}
	t.Cleanup(func() { _ = first.Release() })

	if _, err := AcquireInstanceLock(); !errors.Is(err, ErrInstanceLocked) {
		t.Fatalf("second AcquireInstanceLock() error = %v, want ErrInstanceLocked", err)
	}

	runtimeInfo, err := os.Stat(profile.RuntimeDir())
	if err != nil {
		t.Fatalf("stat runtime directory: %v", err)
	}
	if got := runtimeInfo.Mode().Perm(); runtime.GOOS != "windows" && got != 0o700 {
		t.Fatalf("runtime directory mode = %04o, want 0700", got)
	}
	lockInfo, err := os.Stat(filepath.Join(profile.RuntimeDir(), "daemon.lock"))
	if err != nil {
		t.Fatalf("stat instance lock file: %v", err)
	}
	if got := lockInfo.Mode().Perm(); runtime.GOOS != "windows" && got != 0o600 {
		t.Fatalf("instance lock file mode = %04o, want 0600", got)
	}

	if err := first.Release(); err != nil {
		t.Fatalf("first Release() error = %v", err)
	}
	if err := first.Release(); err != nil {
		t.Fatalf("repeated Release() error = %v", err)
	}

	reacquired, err := AcquireInstanceLock()
	if err != nil {
		t.Fatalf("AcquireInstanceLock() after release error = %v", err)
	}
	if err := reacquired.Release(); err != nil {
		t.Fatalf("reacquired Release() error = %v", err)
	}
}
