package datamysql

import (
	"database/sql"

	"bitbucket.org/nemt/nemt-portal-api/domain/contract"
	"bitbucket.org/nemt/nemt-portal-api/infra/errors"
)

type transaction struct {
	tx            *sql.Tx
	users         *userRepo
	rides         *rideRepo
	visits        *visitRepo
	provider      *providerRepo
	notification  *notificationRepo
	profile       *profileRepo
	organization  *organizationRepo
	zipcodes      *zipcodeRepo
	plan          *planRepo
	passwordReset *passwordResetRepo
}

func newTransaction(tx *sql.Tx) *transaction {

	t := new(transaction)

	t.tx = tx
	t.users = newUserRepo(tx)
	t.rides = newRideRepo(tx)
	t.visits = newVisitRepo(tx)
	t.provider = newProviderRepo(tx)
	t.notification = newNotificationRepo(tx)
	t.profile = newProfileRepo(tx)
	t.organization = newOrganizationRepo(tx)
	t.zipcodes = newZipcodeRepo(tx)
	t.plan = newPlanRepo(tx)
	t.passwordReset = newPasswordResetRepo(tx)

	return t
}

// Users returns the users set
func (t transaction) Users() contract.UserRepo {
	return t.users
}

// Rides returns the rides set
func (t transaction) Rides() contract.RideRepo {
	return t.rides
}

// Rides returns the rides set
func (t transaction) Visits() contract.VisitRepo {
	return t.visits
}

// Provider returns the rides set
func (t transaction) Provider() contract.ProviderRepo {
	return t.provider
}

// Provider returns the rides set
func (t transaction) Profile() contract.ProfileRepo {
	return t.profile
}

// Provider returns the rides set
func (t transaction) Notification() contract.NotificationRepo {
	return t.notification
}

// Provider returns the rides set
func (t transaction) Organization() contract.OrganizationRepo {
	return t.organization
}

func (t transaction) Zipcodes() contract.ZipcodeRepo {
	return t.zipcodes
}

func (t transaction) Plans() contract.PlanRepo {
	return t.plan
}

func (t transaction) PasswordReset() contract.PasswordResetRepo {
	return t.passwordReset
}

func (t *transaction) Commit() error {

	err := t.tx.Commit()
	if err != nil {
		return errors.Wrap(err)
	}

	return nil
}

func (t *transaction) Rollback() error {

	err := t.tx.Rollback()
	if err != nil {
		return errors.Wrap(err)
	}

	return nil
}
