package htpasswd

import (
	"os"
	"testing"
)

func TestParseHtpasswd(t *testing.T) {
	passwords, err := ParseHtpasswd([]byte("sha:{SHA}IRRjboXT92QSYXm8lpGPCZUvU1E=\n"))
	if err != nil {
		t.Fatal(err)
	}
	if len(passwords) != 1 {
		t.Fatalf("unexpected length in passwords, expected 1 got %v", len(passwords))
	}
	const expected = "{SHA}IRRjboXT92QSYXm8lpGPCZUvU1E="
	if passwords["sha"] != expected {
		t.Fatalf("sha password was wrong, got %s and expected %s", passwords["sha"], expected)
	}
}

func TestCreateUser(t *testing.T) {
	f, err := os.Create("htpasswd_testdata")
	if err != nil {
		t.Fatal(err)
	}
	testCases := []struct {
		user, password string
		hash           Hasher
		expected       error
	}{
		{"apr1", "123456@", new(Apr1), nil},
		{"bcrypt", "123456@", new(Bcrypt), nil},
		{"ssha", "123456@", new(Ssha), nil},
		{"sha", "123456@", new(Sha), nil},
		{"sha256", "123456@", new(Sha256), nil},
		{"sha512", "123456@", new(Sha512), nil},
	}

	for _, tc := range testCases {
		err := CreateUser(f.Name(), tc.user, tc.password, tc.hash)
		if err != tc.expected {
			t.Errorf("CreateUser(%s %s, %s, %s) = %d; want %d", f.Name(),
				tc.user, tc.password, tc.hash, err, tc.expected)
		}
	}
}
func TestVerifyPassword(t *testing.T) {
	f, err := os.Stat("htpasswd_testdata")
	if err != nil {
		TestCreateUser(t)
	}

	_, err = ParseHtpasswdFile(f.Name())
	if err != nil {
		t.Fatal(err)
	}

	testCases := []struct {
		user, password string
		expected       error
	}{
		{"apr1", "123456@", nil},
		{"bcrypt", "123456@", nil},
		{"ssha", "123456@", nil},
		{"sha", "123456@", nil},
		{"sha256", "123456@", nil},
		{"sha512", "123456@", nil},
	}

	for _, tc := range testCases {
		err := VerifyUser(f.Name(), tc.user, tc.password)
		if err != tc.expected {
			t.Errorf("VerifyUser(%v %v, %v) = %v; want %v",
				f, tc.user, tc.password, err, tc.expected)
		}
	}
}

func TestVerifyUser(t *testing.T) {
	f, err := os.Stat("htpasswd_testdata")
	if err != nil {
		TestCreateUser(t)
	}

	pp, err := ParseHtpasswdFile(f.Name())
	if err != nil {
		t.Fatal(err)
	}
	testCases := []struct {
		user, password string
		expected       error
	}{
		{"apr1", "123456@", nil},
		{"bcrypt", "123456@", nil},
		{"ssha", "123456@", nil},
		{"sha", "123456@", nil},
		{"sha256", "123456@", nil},
		{"sha512", "123456@", nil},
	}

	for _, tc := range testCases {
		err := pp.VerifyUser(tc.user, tc.password)
		if err != tc.expected {
			t.Errorf("VerifyUser(%s, %s) = %v; want %v",
				tc.user, tc.password, err, tc.expected)
		}
	}
}