package storages

import (
	"github.com/allegro/akubra/internal/akubra/storages/config"
	"net/http"
	"net/url"
	"testing"

	"github.com/allegro/akubra/internal/akubra/storages/backend"
	"github.com/allegro/akubra/internal/akubra/transport"
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/mock"
)

type MockedRoundTripper struct {
	mock.Mock
	transport.Matcher
}

func (mockedRoundTripper *MockedRoundTripper) RoundTrip(request *http.Request) (response *http.Response, err error) {

	args := mockedRoundTripper.Called(request)

	return args.Get(0).(*http.Response), args.Error(1)
}

func TestShouldReturnEmptyRingWhenProvidedBackendListIsEmpty(testSuite *testing.T) {
	emptyBackendsList := []*backend.Backend{}
	multiPartRoundTripper := newMultiPartRoundTripper(emptyBackendsList)
	mprt, ok := multiPartRoundTripper.(*MultiPartRoundTripper)
	assert.True(testSuite, ok)
	assert.Equal(testSuite, mprt.backendsRing.Size(), 0)
	assert.Empty(testSuite, mprt.backendsEndpoints, 0)
}

func TestShouldSetupMultiUploadRingAndMigrationEndpoints(testSuite *testing.T) {

	activeBackendRoundTripper := &MockedRoundTripper{}
	activeBackendRoundTripper2 := &MockedRoundTripper{}

	activeBackendURL, _ := url.Parse("http://backend:1234")
	activeBackendURL2, _ := url.Parse("http://backend2:1234")

	activateBackend := &StorageClient{
		RoundTripper: activeBackendRoundTripper,
		Endpoint:     *activeBackendURL,
		Storage:      config.Storage{Maintenance: false},
		Name:         "activateBackend",
	}

	activateBackend2 := &StorageClient{
		RoundTripper: activeBackendRoundTripper2,
		Endpoint:     *activeBackendURL2,
		Storage:      config.Storage{Maintenance: false},
		Name:         "activateBackend2",
	}

	maintenanceBackendURL, _ := url.Parse("http://maintenance:8421")

	maintenanceBackend := &StorageClient{
		RoundTripper: nil,
		Endpoint:     *maintenanceBackendURL,
		Storage:      config.Storage{Maintenance: true},
		Name:         "maintenanceBackend",
	}

	backends := []*StorageClient{activateBackend, activateBackend2, maintenanceBackend}
	multiPartRoundTripper := newMultiPartRoundTripper(backends)
	mprt, ok := multiPartRoundTripper.(*MultiPartRoundTripper)
	assert.True(testSuite, ok)
	assert.Len(testSuite, mprt.backendsRoundTrippers, 2)
	assert.Equal(testSuite, 2, mprt.backendsRing.Size())
	assert.Len(testSuite, mprt.backendsEndpoints, 3)
}
