package booking_test

import (
	"testing"
	"time"

	"github.com/stretchr/testify/assert"

	"cloud.o-forge.io/core/oc-lib/models/booking"
	"cloud.o-forge.io/core/oc-lib/models/common/enum"
	"cloud.o-forge.io/core/oc-lib/models/utils"
	"cloud.o-forge.io/core/oc-lib/tools"
)

func TestBooking_GetDurations(t *testing.T) {
	start := time.Now().Add(-2 * time.Hour)
	end := start.Add(1 * time.Hour)
	realStart := start.Add(30 * time.Minute)
	realEnd := realStart.Add(90 * time.Minute)

	b := &booking.Booking{
		ExpectedStartDate: start,
		ExpectedEndDate:   &end,
		RealStartDate:     &realStart,
		RealEndDate:       &realEnd,
	}

	assert.Equal(t, 30*time.Minute, b.GetDelayForLaunch())
	assert.Equal(t, 90*time.Minute, b.GetRealDuration())
	assert.Equal(t, end.Sub(start), b.GetUsualDuration())
	assert.Equal(t, b.GetRealDuration()-b.GetUsualDuration(), b.GetDelayOnDuration())
	assert.Equal(t, realEnd.Sub(start), b.GetDelayForFinishing())
}

func TestBooking_GetAccessor(t *testing.T) {
	req := &tools.APIRequest{}
	b := &booking.Booking{}
	accessor := b.GetAccessor(req)

	assert.NotNil(t, accessor)
	assert.Equal(t, tools.BOOKING, accessor.(*booking.BookingMongoAccessor).Type)
}

func TestBooking_VerifyAuth(t *testing.T) {
	assert.True(t, (&booking.Booking{}).VerifyAuth(nil))
}

func TestBooking_StoreDraftDefault(t *testing.T) {
	b := &booking.Booking{}
	b.StoreDraftDefault()
	assert.False(t, b.IsDraft)
}

func TestBooking_CanUpdate(t *testing.T) {
	now := time.Now()
	b := &booking.Booking{
		State:          enum.SCHEDULED,
		AbstractObject: utils.AbstractObject{IsDraft: false},
		RealStartDate:  &now,
	}

	set := &booking.Booking{
		State:         enum.DELAYED,
		RealStartDate: &now,
	}

	ok, result := b.CanUpdate(set)
	assert.True(t, ok)
	assert.Equal(t, enum.DELAYED, result.(*booking.Booking).State)
}

func TestBooking_CanDelete(t *testing.T) {
	b := &booking.Booking{AbstractObject: utils.AbstractObject{IsDraft: true}}
	assert.True(t, b.CanDelete())

	b.IsDraft = false
	assert.False(t, b.CanDelete())
}

func TestNewAccessor(t *testing.T) {
	req := &tools.APIRequest{}
	accessor := booking.NewAccessor(req)

	assert.NotNil(t, accessor)
	assert.Equal(t, tools.BOOKING, accessor.Type)
	assert.Equal(t, req, accessor.Request)
}