package api

import (
	"context"
	"os"
	"path/filepath"
	"testing"

	ppb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/pnd"
	spb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/southbound"
	tpb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/transport"
	"code.fbi.h-da.de/danet/gosdn/controller/nucleus"
	"code.fbi.h-da.de/danet/gosdn/controller/store"
	log "github.com/sirupsen/logrus"
	"github.com/spf13/viper"
)

func Test_Init(t *testing.T) {
	viper.SetConfigFile("./api_test.toml")
	if err := Init(context.TODO(), bufnet); err != nil {
		t.Error(err)
	}
}

func Test_GetIds(t *testing.T) {
	resp, err := GetIds(context.TODO(), bufnet)
	if err != nil {
		t.Error(err)
		return
	}
	log.Info(resp)
}

func ensureFilesForTestsAreRemoved() {
	ensureStoreFileForTestsIsRemoved(store.SbiFilenameSuffix)
	ensureStoreFileForTestsIsRemoved(store.NetworkElementFilenameSuffix)
}

func ensureStoreFileForTestsIsRemoved(storeName string) {
	if err := store.EnsureFilesystemStorePathExists(storeName); err != nil {
		log.Println(err)
	}

	wildcartFilename := "*" + storeName
	path := store.GetCompletePathToFileStore(wildcartFilename)

	files, err := filepath.Glob(path)

	if err != nil {
		log.Println(err)
	}
	for _, f := range files {
		if err := os.Remove(f); err != nil {
			log.Println(err)
		}
	}
}

func Test_AddPnd(t *testing.T) {
	defer ensureFilesForTestsAreRemoved()

	sbi, err := nucleus.NewSBI(spb.Type_TYPE_OPENCONFIG)
	if err != nil {
		t.Errorf("AddPnd() error = %v", err)
	}
	resp, err := AddPnd(context.TODO(), bufnet, "test", "test pnd", sbi.ID().String())
	if err != nil {
		t.Error(err)
		return
	}
	log.Info(resp)
}

func Test_GetPnd(t *testing.T) {
	resp, err := GetPnd(context.TODO(), bufnet, pndID)
	if err != nil {
		t.Error(err)
		return
	}
	got := resp.Pnd.Id
	if got != pndID {
		t.Errorf("PND ID is %v, expected %v", got, pndID)
	}
}

func Test_GetChanges(t *testing.T) {
	resp, err := GetChanges(context.TODO(), bufnet, pndID)
	if err != nil {
		t.Error(err)
		return
	}
	log.Info(resp)
}

func Test_CommitConfirm(t *testing.T) {
	resp, err := Commit(context.TODO(), bufnet, pndID, changeID)
	if err != nil {
		t.Error(err)
		return
	}
	log.Info(resp)

	resp, err = Confirm(context.TODO(), bufnet, pndID, changeID)
	if err != nil {
		t.Error(err)
		return
	}
	log.Info(resp)
}

func Test_AddDevice(t *testing.T) {
	opt := &tpb.TransportOption{
		Address:  "test",
		Username: "test",
		Password: "test",
		TransportOption: &tpb.TransportOption_GnmiTransportOption{
			GnmiTransportOption: &tpb.GnmiTransportOption{},
		},
	}
	resp, err := AddNetworkElement(context.TODO(), bufnet, "test", opt, sbiUUID, pndUUID)
	if err != nil {
		t.Error(err)
		return
	}
	log.Info(resp)
}

func Test_GetDevice(t *testing.T) {
	resp, err := GetNetworkElement(context.TODO(), bufnet, pndID, mneID)
	if err != nil {
		t.Error(err)
		return
	}
	got := resp.Mne.Id
	if got != mneID {
		t.Errorf("PND ID is %v, expected %v", got, mneID)
	}
}

func Test_Update(t *testing.T) {
	resp, err := ChangeRequest(context.TODO(), bufnet, mneID, pndID, "", "", ppb.ApiOperation_API_OPERATION_UPDATE)
	if err != nil {
		t.Error(err)
		return
	}
	log.Info(resp)
}

func Test_Replace(t *testing.T) {
	resp, err := ChangeRequest(context.TODO(), bufnet, mneID, pndID, "", "", ppb.ApiOperation_API_OPERATION_REPLACE)
	if err != nil {
		t.Error(err)
		return
	}
	log.Info(resp)
}

func Test_Delete(t *testing.T) {
	resp, err := ChangeRequest(context.TODO(), bufnet, mneID, pndID, "", "", ppb.ApiOperation_API_OPERATION_DELETE)
	if err != nil {
		t.Error(err)
		return
	}
	log.Info(resp)
}