package cryptext

import (
	"gogs.mikescher.com/BlackForestBytes/goext/langext"
	"gogs.mikescher.com/BlackForestBytes/goext/totpext"
	"gogs.mikescher.com/BlackForestBytes/goext/tst"
	"testing"
)

func TestPassHash1(t *testing.T) {
	ph, err := HashPassword("test123", nil)
	tst.AssertNoErr(t, err)

	tst.AssertTrue(t, ph.Valid())
	tst.AssertFalse(t, ph.HasTOTP())
	tst.AssertFalse(t, ph.NeedsPasswordUpgrade())

	tst.AssertTrue(t, ph.Verify("test123", nil))
	tst.AssertFalse(t, ph.Verify("test124", nil))
}

func TestPassHashTOTP(t *testing.T) {
	sec, err := totpext.GenerateSecret()
	tst.AssertNoErr(t, err)

	ph, err := HashPassword("test123", sec)
	tst.AssertNoErr(t, err)

	tst.AssertTrue(t, ph.Valid())
	tst.AssertTrue(t, ph.HasTOTP())
	tst.AssertFalse(t, ph.NeedsPasswordUpgrade())

	tst.AssertFalse(t, ph.Verify("test123", nil))
	tst.AssertFalse(t, ph.Verify("test124", nil))
	tst.AssertTrue(t, ph.Verify("test123", langext.Ptr(totpext.TOTP(sec))))
	tst.AssertFalse(t, ph.Verify("test124", nil))
}

func TestPassHashUpgrade_V0(t *testing.T) {
	ph, err := HashPasswordV0("test123")
	tst.AssertNoErr(t, err)

	tst.AssertTrue(t, ph.Valid())
	tst.AssertFalse(t, ph.HasTOTP())
	tst.AssertTrue(t, ph.NeedsPasswordUpgrade())

	tst.AssertTrue(t, ph.Verify("test123", nil))
	tst.AssertFalse(t, ph.Verify("test124", nil))

	ph, err = ph.Upgrade("test123")
	tst.AssertNoErr(t, err)

	tst.AssertTrue(t, ph.Valid())
	tst.AssertFalse(t, ph.HasTOTP())
	tst.AssertFalse(t, ph.NeedsPasswordUpgrade())

	tst.AssertTrue(t, ph.Verify("test123", nil))
	tst.AssertFalse(t, ph.Verify("test124", nil))

}

func TestPassHashUpgrade_V1(t *testing.T) {
	ph, err := HashPasswordV1("test123")
	tst.AssertNoErr(t, err)

	tst.AssertTrue(t, ph.Valid())
	tst.AssertFalse(t, ph.HasTOTP())
	tst.AssertTrue(t, ph.NeedsPasswordUpgrade())

	tst.AssertTrue(t, ph.Verify("test123", nil))
	tst.AssertFalse(t, ph.Verify("test124", nil))

	ph, err = ph.Upgrade("test123")
	tst.AssertNoErr(t, err)

	tst.AssertTrue(t, ph.Valid())
	tst.AssertFalse(t, ph.HasTOTP())
	tst.AssertFalse(t, ph.NeedsPasswordUpgrade())

	tst.AssertTrue(t, ph.Verify("test123", nil))
	tst.AssertFalse(t, ph.Verify("test124", nil))

}

func TestPassHashUpgrade_V2(t *testing.T) {
	ph, err := HashPasswordV2("test123")
	tst.AssertNoErr(t, err)

	tst.AssertTrue(t, ph.Valid())
	tst.AssertFalse(t, ph.HasTOTP())
	tst.AssertTrue(t, ph.NeedsPasswordUpgrade())

	tst.AssertTrue(t, ph.Verify("test123", nil))
	tst.AssertFalse(t, ph.Verify("test124", nil))

	ph, err = ph.Upgrade("test123")
	tst.AssertNoErr(t, err)

	tst.AssertTrue(t, ph.Valid())
	tst.AssertFalse(t, ph.HasTOTP())
	tst.AssertFalse(t, ph.NeedsPasswordUpgrade())

	tst.AssertTrue(t, ph.Verify("test123", nil))
	tst.AssertFalse(t, ph.Verify("test124", nil))

}

func TestPassHashUpgrade_V3(t *testing.T) {
	ph, err := HashPasswordV3("test123", nil)
	tst.AssertNoErr(t, err)

	tst.AssertTrue(t, ph.Valid())
	tst.AssertFalse(t, ph.HasTOTP())
	tst.AssertTrue(t, ph.NeedsPasswordUpgrade())

	tst.AssertTrue(t, ph.Verify("test123", nil))
	tst.AssertFalse(t, ph.Verify("test124", nil))

	ph, err = ph.Upgrade("test123")
	tst.AssertNoErr(t, err)

	tst.AssertTrue(t, ph.Valid())
	tst.AssertFalse(t, ph.HasTOTP())
	tst.AssertFalse(t, ph.NeedsPasswordUpgrade())

	tst.AssertTrue(t, ph.Verify("test123", nil))
	tst.AssertFalse(t, ph.Verify("test124", nil))

}

func TestPassHashUpgrade_V3_TOTP(t *testing.T) {
	sec, err := totpext.GenerateSecret()
	tst.AssertNoErr(t, err)

	ph, err := HashPasswordV3("test123", sec)
	tst.AssertNoErr(t, err)

	tst.AssertTrue(t, ph.Valid())
	tst.AssertTrue(t, ph.HasTOTP())
	tst.AssertTrue(t, ph.NeedsPasswordUpgrade())

	tst.AssertFalse(t, ph.Verify("test123", nil))
	tst.AssertFalse(t, ph.Verify("test124", nil))
	tst.AssertTrue(t, ph.Verify("test123", langext.Ptr(totpext.TOTP(sec))))
	tst.AssertFalse(t, ph.Verify("test124", nil))

	ph, err = ph.Upgrade("test123")
	tst.AssertNoErr(t, err)

	tst.AssertTrue(t, ph.Valid())
	tst.AssertTrue(t, ph.HasTOTP())
	tst.AssertFalse(t, ph.NeedsPasswordUpgrade())

	tst.AssertFalse(t, ph.Verify("test123", nil))
	tst.AssertFalse(t, ph.Verify("test124", nil))
	tst.AssertTrue(t, ph.Verify("test123", langext.Ptr(totpext.TOTP(sec))))
	tst.AssertFalse(t, ph.Verify("test124", nil))
}

func TestPassHashUpgrade_V4(t *testing.T) {
	ph, err := HashPasswordV4("test123", nil)
	tst.AssertNoErr(t, err)

	tst.AssertTrue(t, ph.Valid())
	tst.AssertFalse(t, ph.HasTOTP())
	tst.AssertTrue(t, ph.NeedsPasswordUpgrade())

	tst.AssertTrue(t, ph.Verify("test123", nil))
	tst.AssertFalse(t, ph.Verify("test124", nil))

	ph, err = ph.Upgrade("test123")
	tst.AssertNoErr(t, err)

	tst.AssertTrue(t, ph.Valid())
	tst.AssertFalse(t, ph.HasTOTP())
	tst.AssertFalse(t, ph.NeedsPasswordUpgrade())

	tst.AssertTrue(t, ph.Verify("test123", nil))
	tst.AssertFalse(t, ph.Verify("test124", nil))

}

func TestPassHashUpgrade_V4_TOTP(t *testing.T) {
	sec, err := totpext.GenerateSecret()
	tst.AssertNoErr(t, err)

	ph, err := HashPasswordV4("test123", sec)
	tst.AssertNoErr(t, err)

	tst.AssertTrue(t, ph.Valid())
	tst.AssertTrue(t, ph.HasTOTP())
	tst.AssertTrue(t, ph.NeedsPasswordUpgrade())

	tst.AssertFalse(t, ph.Verify("test123", nil))
	tst.AssertFalse(t, ph.Verify("test124", nil))
	tst.AssertTrue(t, ph.Verify("test123", langext.Ptr(totpext.TOTP(sec))))
	tst.AssertFalse(t, ph.Verify("test124", nil))

	ph, err = ph.Upgrade("test123")
	tst.AssertNoErr(t, err)

	tst.AssertTrue(t, ph.Valid())
	tst.AssertTrue(t, ph.HasTOTP())
	tst.AssertFalse(t, ph.NeedsPasswordUpgrade())

	tst.AssertFalse(t, ph.Verify("test123", nil))
	tst.AssertFalse(t, ph.Verify("test124", nil))
	tst.AssertTrue(t, ph.Verify("test123", langext.Ptr(totpext.TOTP(sec))))
	tst.AssertFalse(t, ph.Verify("test124", nil))
}