package main

import (
	"os"
	"path/filepath"
	"testing"
)

func TestSingletonLock_FirstLockSuccess(t *testing.T) {
	lockPath := filepath.Join(os.TempDir(), "nex-gateway-test-first.lock")
	defer os.Remove(lockPath)

	lock := NewSingletonLock(lockPath)
	if err := lock.Lock(); err != nil {
		t.Fatalf("首次加锁应成功，但返回错误: %v", err)
	}
	defer func() {
		if err := lock.Unlock(); err != nil {
			t.Fatalf("解锁失败: %v", err)
		}
	}()
}

func TestSingletonLock_DuplicateLockFails(t *testing.T) {
	lockPath := filepath.Join(os.TempDir(), "nex-gateway-test-dup.lock")
	defer os.Remove(lockPath)

	lock1 := NewSingletonLock(lockPath)
	if err := lock1.Lock(); err != nil {
		t.Fatalf("首次加锁应成功: %v", err)
	}
	defer func() {
		if err := lock1.Unlock(); err != nil {
			t.Fatalf("解锁失败: %v", err)
		}
	}()

	lock2 := NewSingletonLock(lockPath)
	err := lock2.Lock()
	if err == nil {
		if unlockErr := lock2.Unlock(); unlockErr != nil {
			t.Fatalf("解锁失败: %v", unlockErr)
		}
		t.Fatal("重复加锁应失败，但返回 nil")
	}
}

func TestSingletonLock_UnlockThenRelock(t *testing.T) {
	lockPath := filepath.Join(os.TempDir(), "nex-gateway-test-relock.lock")
	defer os.Remove(lockPath)

	lock1 := NewSingletonLock(lockPath)
	if err := lock1.Lock(); err != nil {
		t.Fatalf("首次加锁应成功: %v", err)
	}
	if err := lock1.Unlock(); err != nil {
		t.Fatalf("解锁失败: %v", err)
	}

	lock2 := NewSingletonLock(lockPath)
	if err := lock2.Lock(); err != nil {
		t.Fatalf("释放后重新加锁应成功: %v", err)
	}
	if err := lock2.Unlock(); err != nil {
		t.Fatalf("解锁失败: %v", err)
	}
}

func TestSingletonLock_UnlockWithoutLock(t *testing.T) {
	lock := NewSingletonLock(filepath.Join(os.TempDir(), "nex-gateway-test-nil.lock"))
	if err := lock.Unlock(); err != nil {
		t.Fatalf("未加锁时解锁失败: %v", err)
	}
}
