package integration

// import (
// 	"context"
// 	"os"
// 	"reflect"
// 	"sort"
// 	"testing"
// 	"time"

// 	"github.com/google/uuid"

// 	mnepb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/networkelement"
// 	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/interfaces/change"
// 	"code.fbi.h-da.de/danet/gosdn/controller/mocks"
// 	"code.fbi.h-da.de/danet/gosdn/models/generated/openconfig"
// 	"code.fbi.h-da.de/danet/gosdn/plugins/sdk"

// 	"code.fbi.h-da.de/danet/gosdn/controller/customerrs"
// 	"code.fbi.h-da.de/danet/gosdn/controller/nucleus"
// 	"code.fbi.h-da.de/danet/gosdn/controller/nucleus/types"
// 	"code.fbi.h-da.de/danet/gosdn/controller/nucleus/util/proto"
// 	"code.fbi.h-da.de/danet/gosdn/forks/goarista/gnmi"
// 	"github.com/google/uuid"
// 	gpb "github.com/openconfig/gnmi/proto/gnmi"
// 	log "github.com/sirupsen/logrus"
// 	pb "google.golang.org/protobuf/proto"
// )

// const unreachable = "203.0.113.10:6030"
// const testPath = "/system/config/hostname"

// var modifiedHostname = "ceos3000"
// var testAddress = "10.254.254.105:6030"
// var testUsername = "admin"
// var testPassword = "arista"
// var opt *tpb.TransportOption
// var gnmiMessages map[string]pb.Message

// func TestMain(m *testing.M) {
// 	testSetupIntegration()
// 	os.Exit(m.Run())
// }

// func testSetupIntegration() {
// 	if os.Getenv("GOSDN_LOG") == "nolog" {
// 		log.SetLevel(log.PanicLevel)
// 	}

// 	addr := os.Getenv("CEOS_TEST_ENDPOINT")
// 	if addr != "" {
// 		testAddress = addr
// 		log.Infof("CEOS_TEST_ENDPOINT set to %v", testAddress)
// 	}
// 	u := os.Getenv("GOSDN_TEST_USER")
// 	if u != "" {
// 		testUsername = u
// 		log.Infof("GOSDN_TEST_USER set to %v", testUsername)
// 	}
// 	p := os.Getenv("GOSDN_TEST_PASSWORD")
// 	if p != "" {
// 		testPassword = p
// 		log.Infof("GOSDN_TEST_PASSWORD set to %v", testPassword)
// 	}

// 	gnmiMessages = map[string]pb.Message{
// 		"../proto/cap-resp-arista-ceos":                  &gpb.CapabilityResponse{},
// 		"../proto/req-full-node":                         &gpb.GetRequest{},
// 		"../proto/req-full-node-arista-ceos":             &gpb.GetRequest{},
// 		"../proto/req-interfaces-arista-ceos":            &gpb.GetRequest{},
// 		"../proto/req-interfaces-interface-arista-ceos":  &gpb.GetRequest{},
// 		"../proto/req-interfaces-wildcard":               &gpb.GetRequest{},
// 		"../proto/resp-full-node":                        &gpb.GetResponse{},
// 		"../proto/resp-full-node-arista-ceos":            &gpb.GetResponse{},
// 		"../proto/resp-interfaces-arista-ceos":           &gpb.GetResponse{},
// 		"../proto/resp-interfaces-interface-arista-ceos": &gpb.GetResponse{},
// 		"../proto/resp-interfaces-wildcard":              &gpb.GetResponse{},
// 		"../proto/resp-set-system-config-hostname":       &gpb.SetResponse{},
// 	}
// 	for k, v := range gnmiMessages {
// 		if err := proto.Read(k, v); err != nil {
// 			log.Fatalf("error parsing %v: %v", k, err)
// 		}
// 	}

// 	opt = &tpb.TransportOption{
// 		Address:  testAddress,
// 		Username: testUsername,
// 		Password: testPassword,
// 		TransportOption: &tpb.TransportOption_GnmiTransportOption{
// 			GnmiTransportOption: &tpb.GnmiTransportOption{},
// 		},
// 	}
// }

// func TestGnmi_SetInvalidIntegration(t *testing.T) {
// 	if testing.Short() {
// 		t.Skip("skipping integration test")
// 	}
// 	type fields struct {
// 		opt *tpb.TransportOption
// 	}
// 	type args struct {
// 		ctx     context.Context
// 		payload change.Payload
// 		path    string
// 	}
// 	tests := []struct {
// 		name    string
// 		fields  fields
// 		args    args
// 		wantErr bool
// 	}{
// 		{
// 			name: "destination unreachable",
// 			fields: fields{
// 				opt: &tpb.TransportOption{
// 					Address: unreachable,
// 					TransportOption: &tpb.TransportOption_GnmiTransportOption{
// 						GnmiTransportOption: &tpb.GnmiTransportOption{}},
// 				},
// 			},
// 			args: args{
// 				ctx:     context.Background(),
// 				payload: change.Payload{},
// 				path:    "/",
// 			},
// 			wantErr: true,
// 		},
// 		{
// 			name:   "invalid update",
// 			fields: fields{opt: opt},
// 			args: args{
// 				ctx:     context.Background(),
// 				payload: change.Payload{},
// 				path:    "/",
// 			},
// 			wantErr: true,
// 		},
// 	}
// 	for _, tt := range tests {
// 		t.Run(tt.name, func(t *testing.T) {
// 			deviceModel, err := sdk.NewDeviceModel(openconfig.Schema, openconfig.Unmarshal, openconfig.SchemaTreeGzip)
// 			if err != nil {
// 				t.Errorf("SetInvalidIntegration() error = %v", err)
// 				return
// 			}
// 			g, err := nucleus.NewTransport(tt.fields.opt, deviceModel)
// 			if (err != nil) != tt.wantErr {
// 				t.Errorf("SetInvalidIntegration() error = %v, wantErr %v", err, tt.wantErr)
// 				return
// 			}
// 			err = g.Set(tt.args.ctx, tt.args.payload, tt.args.path, &mocks.Plugin{})
// 			if (err != nil) != tt.wantErr {
// 				t.Errorf("SetInvalidIntegration() error = %v, wantErr %v", err, tt.wantErr)
// 				return
// 			}
// 		})
// 	}
// }

// func TestGnmi_SetValidIntegration(t *testing.T) {
// 	if testing.Short() {
// 		t.Skip("skipping integration test")
// 	}

// 	opt := &tpb.TransportOption{
// 		Address:  testAddress,
// 		Username: testUsername,
// 		Password: testPassword,
// 		TransportOption: &tpb.TransportOption_GnmiTransportOption{
// 			GnmiTransportOption: &tpb.GnmiTransportOption{},
// 		},
// 	}
// 	pnd, err := nucleus.NewPND("test", "test", uuid.New(), nil, nil, nil, nil)
// 	if err != nil {
// 		t.Error(err)
// 		return
// 	}
// 	_, err = pnd.AddNetworkElement("test", opt, nil, uuid.New(), pnd.ID())
// 	if err != nil {
// 		t.Error(err)
// 		return
// 	}
// 	mne, err := pnd.GetNetworkElement("test")
// 	if err != nil {
// 		t.Error(err)
// 		return
// 	}

// 	tests := []struct {
// 		name  string
// 		apiOp mnepb.ApiOperation
// 		path  string
// 		value string
// 		want  string
// 	}{
// 		{
// 			name:  "update",
// 			apiOp: mnepb.ApiOperation_API_OPERATION_UPDATE,
// 			path:  testPath,
// 			value: modifiedHostname,
// 			want:  modifiedHostname,
// 		},
// 		{
// 			name:  "replace",
// 			apiOp: mnepb.ApiOperation_API_OPERATION_REPLACE,
// 			path:  "/system/config/domain-name",
// 			value: modifiedHostname,
// 			want:  modifiedHostname,
// 		},
// 		{
// 			name:  "delete",
// 			apiOp: mnepb.ApiOperation_API_OPERATION_DELETE,
// 			path:  testPath,
// 		},
// 	}
// 	for _, tt := range tests {
// 		tt := tt
// 		t.Run(tt.name, func(t *testing.T) {
// 			t.Parallel()

// 			n := &server.NetworkElementServer{}

// 			cuid, err := n.ChangeMNE(mne.ID(), tt.apiOp, tt.path, tt.value)
// 			if err != nil {
// 				t.Error(err)
// 				return
// 			}
// 			if err := n.Commit(cuid); err != nil {
// 				t.Error(err)
// 				return
// 			}
// 			if err := n.Confirm(cuid); err != nil {
// 				t.Error(err)
// 				return
// 			}
// 			if tt.name != "delete" {
// 				resp, err := pnd.Request(mne.ID(), tt.path)
// 				if err != nil {
// 					t.Error(err)
// 					return
// 				}
// 				r, ok := resp.(*gpb.GetResponse)
// 				if !ok {
// 					t.Error(&customerrs.InvalidTypeAssertionError{
// 						Value: resp,
// 						Type:  &gpb.GetResponse{},
// 					})
// 					return
// 				}
// 				got := r.Notification[0].Update[0].Val.GetStringVal()
// 				if !reflect.DeepEqual(got, tt.want) {
// 					t.Errorf("GetNetworkElement() got = %v, want %v", got, tt.want)
// 				}
// 			}
// 		})
// 	}
// }

// func TestGnmi_GetIntegration(t *testing.T) {
// 	if testing.Short() {
// 		t.Skip("skipping integration test")
// 	}

// 	paths := []string{
// 		"/interfaces/interface",
// 		"system/config/hostname",
// 	}
// 	type fields struct {
// 		opt *tpb.TransportOption
// 	}
// 	type args struct {
// 		ctx    context.Context
// 		params []string
// 	}
// 	tests := []struct {
// 		name    string
// 		fields  fields
// 		args    args
// 		want    interface{}
// 		wantErr bool
// 	}{
// 		{
// 			name:   "default",
// 			fields: fields{opt: opt},
// 			args: args{
// 				ctx:    context.Background(),
// 				params: paths[:1],
// 			},
// 			want:    gnmiMessages["../proto/resp-interfaces-arista-ceos"],
// 			wantErr: false,
// 		},
// 		{
// 			name: "destination unreachable",
// 			fields: fields{
// 				opt: &tpb.TransportOption{
// 					Address: unreachable,
// 					TransportOption: &tpb.TransportOption_GnmiTransportOption{
// 						GnmiTransportOption: &tpb.GnmiTransportOption{}},
// 				},
// 			},
// 			args: args{
// 				ctx:    context.Background(),
// 				params: paths,
// 			},
// 			want:    nil,
// 			wantErr: true,
// 		},
// 	}
// 	for _, tt := range tests {
// 		t.Run(tt.name, func(t *testing.T) {
// 			deviceModel, err := sdk.NewDeviceModel(openconfig.Schema, openconfig.Unmarshal, openconfig.SchemaTreeGzip)
// 			if err != nil {
// 				t.Errorf("Get() error = %v", err)
// 				return
// 			}
// 			g, err := nucleus.NewTransport(tt.fields.opt, deviceModel)
// 			if err != nil {
// 				t.Error(err)
// 				return
// 			}
// 			got, err := g.Get(tt.args.ctx, tt.args.params...)
// 			if (err != nil) != tt.wantErr {
// 				t.Errorf("Get() error = %v, wantErr %v", err, tt.wantErr)
// 				return
// 			}
// 			if reflect.TypeOf(got) != reflect.TypeOf(tt.want) {
// 				t.Errorf("Get() got = %v, want %v", got, tt.want)
// 			}
// 		})
// 	}
// }
// func TestGnmi_SubscribeIntegration(t *testing.T) {
// 	if testing.Short() {
// 		t.Skip("skipping integration test")
// 	}

// 	type fields struct {
// 		opt *tpb.TransportOption
// 	}
// 	type args struct {
// 		ctx  context.Context
// 		opts *gnmi.SubscribeOptions
// 	}
// 	tests := []struct {
// 		name    string
// 		fields  fields
// 		args    args
// 		wantErr bool
// 	}{
// 		{
// 			name: "default",
// 			fields: fields{
// 				opt: &tpb.TransportOption{
// 					Address:  testAddress,
// 					Username: testUsername,
// 					Password: testPassword,
// 					Tls:      false,
// 					TransportOption: &tpb.TransportOption_GnmiTransportOption{
// 						GnmiTransportOption: &tpb.GnmiTransportOption{
// 							Compression:     "",
// 							GrpcDialOptions: nil,
// 							Token:           "",
// 							Encoding:        0,
// 						},
// 					},
// 				},
// 			},
// 			args: args{
// 				ctx: context.Background(),
// 				opts: &gnmi.SubscribeOptions{
// 					Mode:              "stream",
// 					StreamMode:        "sample",
// 					SampleInterval:    uint64(1 * time.Second),
// 					HeartbeatInterval: uint64(100 * time.Millisecond),
// 					Paths: gnmi.SplitPaths([]string{
// 						"/interfaces/interface/name",
// 						"/system/config/hostname",
// 					}),
// 					Target: testAddress,
// 				},
// 			},
// 			wantErr: false,
// 		},
// 		{
// 			name: "wrong path",
// 			fields: fields{
// 				opt: &tpb.TransportOption{
// 					TransportOption: &tpb.TransportOption_GnmiTransportOption{
// 						GnmiTransportOption: &tpb.GnmiTransportOption{}},
// 				},
// 			},
// 			args: args{
// 				opts: &gnmi.SubscribeOptions{
// 					Mode:              "stream",
// 					StreamMode:        "sample",
// 					SampleInterval:    uint64(1 * time.Second),
// 					HeartbeatInterval: uint64(100 * time.Millisecond),
// 					Paths: gnmi.SplitPaths([]string{
// 						"interfaces/interface/name",
// 						"ystem/config/hostname",
// 					}),
// 					Target: testAddress,
// 				},
// 			},
// 			wantErr: true,
// 		},
// 		{
// 			name: "destination unreachable",
// 			fields: fields{
// 				opt: &tpb.TransportOption{
// 					Address: "203.0.113.10:6030",
// 					TransportOption: &tpb.TransportOption_GnmiTransportOption{
// 						GnmiTransportOption: &tpb.GnmiTransportOption{}},
// 				},
// 			},
// 			args: args{
// 				opts: &gnmi.SubscribeOptions{},
// 			},
// 			wantErr: false,
// 		},
// 	}
// 	for _, tt := range tests {
// 		t.Run(tt.name, func(t *testing.T) {
// 			var wantErr = tt.wantErr
// 			deviceModel, err := sdk.NewDeviceModel(openconfig.Schema, openconfig.Unmarshal, openconfig.SchemaTreeGzip)
// 			if err != nil {
// 				t.Errorf("Subscribe() error = %v", err)
// 				return
// 			}
// 			g, err := nucleus.NewTransport(tt.fields.opt, deviceModel)
// 			if err != nil {
// 				t.Error(err)
// 				return
// 			}
// 			ctx := context.WithValue(context.Background(), types.CtxKeyOpts, tt.args.opts) //nolint
// 			ctx, cancel := context.WithCancel(ctx)
// 			go func() {
// 				subErr := g.Subscribe(ctx)
// 				if (subErr != nil) != wantErr {
// 					if !wantErr && subErr != nil {
// 						if subErr.Error() != "rpc error: code = Canceled desc = context canceled" {
// 							t.Errorf("Subscribe() error = %v, wantErr %v", subErr, tt.wantErr)
// 						}
// 					}
// 				}
// 			}()
// 			time.Sleep(time.Second * 3)
// 			cancel()
// 			time.Sleep(time.Second * 1)
// 		})
// 	}
// }

// func TestGnmi_CapabilitiesIntegration(t *testing.T) {
// 	if testing.Short() {
// 		t.Skip("skipping integration test")
// 	}
// 	type fields struct {
// 		opt *tpb.TransportOption
// 	}
// 	type args struct {
// 		ctx context.Context
// 	}
// 	tests := []struct {
// 		name    string
// 		fields  fields
// 		args    args
// 		want    interface{}
// 		wantErr bool
// 	}{
// 		{
// 			name:    "supported models",
// 			fields:  fields{opt: opt},
// 			args:    args{ctx: context.Background()},
// 			want:    gnmiMessages["../proto/cap-resp-arista-ceos"].(*gpb.CapabilityResponse).SupportedModels,
// 			wantErr: false,
// 		},
// 		{
// 			name:    "supported encodings",
// 			fields:  fields{opt: opt},
// 			args:    args{ctx: context.Background()},
// 			want:    gnmiMessages["../proto/cap-resp-arista-ceos"].(*gpb.CapabilityResponse).SupportedEncodings,
// 			wantErr: false,
// 		},
// 		{
// 			name:    "gnmi version",
// 			fields:  fields{opt: opt},
// 			args:    args{ctx: context.Background()},
// 			want:    gnmiMessages["../proto/cap-resp-arista-ceos"].(*gpb.CapabilityResponse).GNMIVersion,
// 			wantErr: false,
// 		},
// 		{
// 			name: "destination unreachable",
// 			fields: fields{opt: &tpb.TransportOption{
// 				Address: "203.0.113.10:6030",
// 				TransportOption: &tpb.TransportOption_GnmiTransportOption{
// 					GnmiTransportOption: &tpb.GnmiTransportOption{}},
// 			},
// 			},
// 			args:    args{ctx: context.Background()},
// 			want:    nil,
// 			wantErr: true,
// 		},
// 	}
// 	for _, tt := range tests {
// 		t.Run(tt.name, func(t *testing.T) {
// 			deviceModel, err := sdk.NewDeviceModel(openconfig.Schema, openconfig.Unmarshal, openconfig.SchemaTreeGzip)
// 			if err != nil {
// 				t.Errorf("Capabilities() error = %v", err)
// 				return
// 			}
// 			tr, err := nucleus.NewTransport(tt.fields.opt, deviceModel)
// 			if err != nil {
// 				t.Error(err)
// 				return
// 			}
// 			g, ok := tr.(*nucleus.Gnmi)
// 			if !ok {
// 				t.Error(&customerrs.InvalidTypeAssertionError{
// 					Value: tr,
// 					Type:  &nucleus.Gnmi{},
// 				})
// 			}
// 			resp, err := g.Capabilities(tt.args.ctx)
// 			if (err != nil) != tt.wantErr {
// 				t.Errorf("Capabilities() error = %v, wantErr %v", err, tt.wantErr)
// 				return
// 			}
// 			var got interface{}
// 			switch tt.name {
// 			case "supported encodings":
// 				got = resp.(*gpb.CapabilityResponse).SupportedEncodings
// 			case "supported models":
// 				t.Skip("test causes false negative")
// 				got = resp.(*gpb.CapabilityResponse).SupportedModels
// 				sort.Slice(got.([]*gpb.ModelData), func(i, j int) bool {
// 					return got.([]*gpb.ModelData)[i].Name < got.([]*gpb.ModelData)[j].Name
// 				})
// 				sort.Slice(tt.want.([]*gpb.ModelData), func(i, j int) bool {
// 					return tt.want.([]*gpb.ModelData)[i].Name < tt.want.([]*gpb.ModelData)[j].Name
// 				})
// 			case "gnmi version":
// 				got = resp.(*gpb.CapabilityResponse).GNMIVersion
// 			default:
// 			}
// 			if !reflect.DeepEqual(got, tt.want) {
// 				t.Errorf("Type() = %v, want %v", got, tt.want)
// 			}
// 		})
// 	}
// }
