package csbi

import (
	"context"
	"net"
	"reflect"
	"testing"

	"code.fbi.h-da.de/danet/gosdn/api/go/gosdn/csbi"
	spb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/southbound"
	"github.com/google/uuid"
	"github.com/openconfig/gnmi/proto/gnmi"
	"google.golang.org/grpc/peer"
)

func TestGenerate(t *testing.T) {
	type args struct {
		model      []*gnmi.ModelData
		repository Repository
		sbiType    spb.Type
		p          *peer.Peer
	}
	tests := []struct {
		name    string
		args    args
		want    Deployment
		wantErr bool
	}{
		{
			name: "csbi",
			args: args{
				repository: NewRepository("testdata/models"),
				sbiType:    spb.Type_TYPE_CONTAINERISED,
				p:          &peer.Peer{Addr: &net.TCPAddr{}},
			},
			want: Deployment{
				ID:    uuid.Nil,
				State: csbi.State_STATE_ANNOUNCED,
			},
			wantErr: false,
		},
		{
			name: "psbi",
			args: args{
				repository: NewRepository("testdata/models"),
				sbiType:    spb.Type_TYPE_PLUGIN,
			},
			want: Deployment{
				ID:    uuid.Nil,
				State: csbi.State_STATE_ANNOUNCED,
			},
			wantErr: false,
		},
		{
			name: "invalid repo",
			args: args{
				repository: NewRepository("testdata/no-models"),
				sbiType:    spb.Type_TYPE_PLUGIN,
			},
			want:    Deployment{},
			wantErr: true,
		},
		{
			name: "invalid model data",
			args: args{
				repository: NewRepository("testdata/models"),
				sbiType:    spb.Type_TYPE_PLUGIN,
				model: []*gnmi.ModelData{
					{
						Name:         "test-model",
						Organization: "danet",
						Version:      "v0.0.1",
					},
				},
			},
			want:    Deployment{},
			wantErr: true,
		},
		{
			name: "no peer info",
			args: args{
				repository: NewRepository("testdata/models"),
				sbiType:    spb.Type_TYPE_CONTAINERISED,
			},
			want:    Deployment{},
			wantErr: true,
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			ctx := context.Background()
			switch tt.name {
			case "csbi":
				ctx = peer.NewContext(ctx, tt.args.p)
			default:
			}
			got, err := Generate(ctx, tt.args.model, tt.args.repository, tt.args.sbiType)
			if (err != nil) != tt.wantErr {
				t.Errorf("Generate() error = %v, wantErr %v", err, tt.wantErr)
				return
			}
			if !reflect.DeepEqual(got, tt.want) {
				t.Errorf("Generate() = %v, want %v", got, tt.want)
			}
		})
	}
}
