package mysql

import (
	"testing"
	"time"

	"github.com/jmoiron/sqlx"
	. "github.com/smartystreets/goconvey/convey"
	"github.com/solefaucet/jackpot-server/models"
)

func TestUpsertGame(t *testing.T) {
	Convey("Given empty mysql storage", t, func() {
		s := prepareDatabaseForTesting()

		Convey("When upsert game", func() {
			err := s.withTx(func(tx *sqlx.Tx) error {
				return upsertGame(tx, "hash", 1, 0.2, time.Now().UTC())
			})

			Convey("Error should be nil", func() {
				So(err, ShouldBeNil)
			})
		})
	})

	Convey("Given empty mysql storage", t, func() {
		s := prepareDatabaseForTesting()

		Convey("When upsert game with commited connection", func() {
			err := s.withTx(func(tx *sqlx.Tx) error {
				tx.Commit()
				return upsertGame(tx, "hash", 1, 0.2, time.Now().UTC())
			})

			Convey("Error should not be nil", func() {
				So(err, ShouldNotBeNil)
			})
		})
	})
}

func TestUpdateGame(t *testing.T) {
	Convey("Given empty mysql storage", t, func() {
		s := prepareDatabaseForTesting()

		Convey("When update game", func() {
			err := s.withTx(func(tx *sqlx.Tx) error {
				return updateGame(tx, nil)
			})

			Convey("Error should be nil", func() {
				So(err, ShouldBeNil)
			})
		})
	})

	Convey("Given mysql storage with one game", t, func() {
		s := prepareDatabaseForTesting()
		now := time.Now().Truncate(time.Hour)
		s.withTx(func(tx *sqlx.Tx) error {
			return upsertGame(tx, "hash", 1, 0.2, now)
		})

		Convey("When update existing game", func() {
			game := &models.Game{
				Address:       "address",
				Hash:          "hi hash",
				Height:        2,
				WinAmount:     0.1,
				Fee:           0.1,
				TransactionID: "tx_id",
				GameOf:        now,
			}
			err := s.withTx(func(tx *sqlx.Tx) error {
				return updateGame(tx, game)
			})

			Convey("Error should be nil", func() {
				So(err, ShouldBeNil)
			})
		})

		Convey("When update non-existing game", func() {
			game := &models.Game{
				Address:       "address",
				Hash:          "hi hash",
				Height:        2,
				WinAmount:     0.1,
				Fee:           0.1,
				TransactionID: "tx_id",
				GameOf:        now.Add(time.Hour),
			}
			err := s.withTx(func(tx *sqlx.Tx) error {
				return updateGame(tx, game)
			})

			Convey("Error should not be nil", func() {
				So(err, ShouldNotBeNil)
			})
		})
	})

	Convey("Given empty mysql storage", t, func() {
		s := prepareDatabaseForTesting()

		Convey("When update game with commited connection", func() {
			err := s.withTx(func(tx *sqlx.Tx) error {
				tx.Commit()
				return updateGame(tx, &models.Game{})
			})

			Convey("Error should not be nil", func() {
				So(err, ShouldNotBeNil)
			})
		})
	})
}
