/*
* Copyright 2022-present Open Networking Foundation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
 */

package controller

import (
	"context"
	"reflect"
	"sync"
	"testing"
	"voltha-go-controller/internal/pkg/intf"
	"voltha-go-controller/internal/pkg/of"
	"voltha-go-controller/internal/pkg/tasks"
	"voltha-go-controller/internal/pkg/vpagent"
	"voltha-go-controller/internal/test/mocks"

	"github.com/golang/mock/gomock"
	"github.com/stretchr/testify/assert"
)

func TestNewController(t *testing.T) {
	type args struct {
		ctx context.Context
		app intf.App
	}
	appMock := mocks.NewMockApp(gomock.NewController(t))
	app := NewController(ctx, appMock)
	tests := []struct {
		name string
		args args
		want intf.IVPClientAgent
	}{
		{
			name: "TestNewController",
			args: args{
				ctx: context.Background(),
				app: GetController().app,
			},
			want: app,
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			if got := NewController(tt.args.ctx, tt.args.app); !reflect.DeepEqual(got, tt.want) {
				t.Errorf("NewController() = %v, want %v", got, tt.want)
			}
		})
	}
}

func Cancel() {}
func TestVoltController_DelDevice(t *testing.T) {
	type args struct {
		cntx context.Context
		id   string
	}

	device := &Device{
		ID:     "SDX6320031",
		cancel: Cancel,
	}
	dev := map[string]*Device{}
	dev["SDX6320031"] = device
	appMock := mocks.NewMockApp(gomock.NewController(t))
	NewController(ctx, appMock)
	appMock.EXPECT().DelDevice(gomock.Any(), gomock.Any()).AnyTimes()
	tests := []struct {
		name string
		args args
	}{
		{
			name: "DelDevice",
			args: args{
				cntx: context.Background(),
				id:   "SDX6320031",
			},
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			v := &VoltController{
				devices: dev,
				app:     GetController().app,
			}
			v.DelDevice(tt.args.cntx, tt.args.id)
		})
	}
}

func TestVoltController_AddFlows(t *testing.T) {
	type args struct {
		cntx   context.Context
		port   string
		device string
		flow   *of.VoltFlow
	}
	subFlows := map[uint64]*of.VoltSubFlow{}
	vltSubFlow := &of.VoltSubFlow{
		Priority: 100,
		Cookie:   103112802816,
		State:    of.FlowAddSuccess,
		Match: of.Match{
			InPort:     1573376,
			MatchVlan:  4096,
			L4Protocol: 255,
		},
		Action: of.Action{
			Metadata:    279189651712,
			GoToTableID: 1,
			MeterID:     1,
			SetVlan:     4097,
			Pcp:         8,
			Output:      4,
		},
	}
	subFlows[0] = vltSubFlow
	portsByName := map[string]*DevicePort{}
	portsByName["SDX6320031-1"] = &DevicePort{
		Name: "SDX6320031-1",
		ID:   256,
	}
	device := &Device{
		ctx:         context.Background(),
		ID:          "SDX6320031",
		flows:       subFlows,
		PortsByName: portsByName,
	}
	dev := map[string]*Device{}
	dev["SDX6320031"] = device
	flow := &of.VoltFlow{
		PortName:      "SDX6320031-1",
		PortID:        256,
		Command:       0,
		MigrateCookie: true,
	}
	tests := []struct {
		name    string
		args    args
		wantErr bool
	}{
		{
			name: "AddFlows",
			args: args{
				cntx:   context.Background(),
				port:   "SDX6320031-1",
				device: "SDX6320031",
				flow:   flow,
			},
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			v := &VoltController{
				devices: dev,
			}
			if err := v.AddFlows(tt.args.cntx, tt.args.port, tt.args.device, tt.args.flow); (err != nil) != tt.wantErr {
				t.Errorf("VoltController.AddFlows() error = %v, wantErr %v", err, tt.wantErr)
			}
		})
	}
}

func TestVoltController_DelFlows(t *testing.T) {
	type args struct {
		cntx   context.Context
		port   string
		device string
		flow   *of.VoltFlow
	}
	subFlows := map[uint64]*of.VoltSubFlow{}
	vltSubFlow := &of.VoltSubFlow{
		Priority: 100,
		Cookie:   103112802816,
		State:    of.FlowAddSuccess,
		Match: of.Match{
			InPort:     1573376,
			MatchVlan:  4096,
			L4Protocol: 255,
		},
		Action: of.Action{
			Metadata:    279189651712,
			GoToTableID: 1,
			MeterID:     1,
			SetVlan:     4097,
			Pcp:         8,
			Output:      4,
		},
	}
	subFlows[0] = vltSubFlow
	portsByName := map[string]*DevicePort{}
	portsByName["SDX6320031-1"] = &DevicePort{
		Name: "SDX6320031-1",
		ID:   256,
	}
	device := &Device{
		ctx:         context.Background(),
		ID:          "SDX6320031",
		flows:       subFlows,
		PortsByName: portsByName,
	}
	dev := map[string]*Device{}
	dev["SDX6320031"] = device
	flow := &of.VoltFlow{
		PortName:      "SDX6320031-1",
		PortID:        256,
		Command:       0,
		MigrateCookie: true,
	}
	tests := []struct {
		name    string
		args    args
		wantErr bool
	}{
		{
			name: "DelFlows",
			args: args{
				cntx:   context.Background(),
				port:   "SDX6320031-1",
				device: "SDX6320031",
				flow:   flow,
			},
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			v := &VoltController{
				devices: dev,
			}
			if err := v.DelFlows(tt.args.cntx, tt.args.port, tt.args.device, tt.args.flow); (err != nil) != tt.wantErr {
				t.Errorf("VoltController.DelFlows() error = %v, wantErr %v", err, tt.wantErr)
			}
		})
	}
}

func TestVoltController_GetGroups(t *testing.T) {
	type args struct {
		cntx context.Context
		id   uint32
	}
	device := &Device{
		ctx:    context.Background(),
		ID:     "SDX6320031",
		groups: sync.Map{},
	}
	grp := &of.Group{
		Device:  "SDX6320031",
		GroupID: uint32(256),
		State:   1,
		SetVlan: of.VlanAny,
	}
	dev := map[string]*Device{}
	dev["SDX6320031"] = device
	tests := []struct {
		name    string
		args    args
		want    *of.Group
		wantErr bool
	}{
		{
			name: "VoltController_GetGroups",
			args: args{
				cntx: context.Background(),
				id:   uint32(256),
			},
			want:    grp,
			wantErr: false,
		},
		{
			name: "GetGroups_Not-Found",
			args: args{
				cntx: context.Background(),
				id:   1,
			},
			want:    nil,
			wantErr: true,
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			v := &VoltController{
				devices: dev,
			}
			switch tt.name {
			case "VoltController_GetGroups":
				device.groups.Store(uint32(256), grp)
				got, err := v.GetGroups(tt.args.cntx, tt.args.id)
				if (err != nil) != tt.wantErr {
					t.Errorf("VoltController.GetGroups() error = %v, wantErr %v", err, tt.wantErr)
					return
				}
				if !reflect.DeepEqual(got, tt.want) {
					t.Errorf("VoltController.GetGroups() = %v, want %v", got, tt.want)
				}
			case "GetGroups_Not-Found":
				got, err := v.GetGroups(tt.args.cntx, tt.args.id)
				if (err != nil) != tt.wantErr {
					t.Errorf("VoltController.GetGroups() error = %v, wantErr %v", err, tt.wantErr)
					return
				}
				if !reflect.DeepEqual(got, tt.want) {
					t.Errorf("VoltController.GetGroups() = %v, want %v", got, tt.want)
				}
			}
		})
	}
}

func TestVoltController_GetGroupList(t *testing.T) {
	device := &Device{
		ctx:    context.Background(),
		ID:     "SDX6320031",
		groups: sync.Map{},
	}
	grpList := []*of.Group{}
	grp := &of.Group{
		Device:  "SDX6320031",
		GroupID: uint32(256),
		State:   1,
		SetVlan: of.VlanAny,
	}
	grpList = append(grpList, grp)
	dev := map[string]*Device{}
	dev["SDX6320031"] = device
	tests := []struct {
		name    string
		want    []*of.Group
		wantErr bool
	}{
		{
			name:    "VoltController_GetGroups",
			want:    grpList,
			wantErr: false,
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			v := &VoltController{
				devices: dev,
			}
			device.groups.Store(uint32(256), grp)
			got, err := v.GetGroupList()
			if (err != nil) != tt.wantErr {
				t.Errorf("VoltController.GetGroupList() error = %v, wantErr %v", err, tt.wantErr)
				return
			}
			if !reflect.DeepEqual(got, tt.want) {
				t.Errorf("VoltController.GetGroupList() = %v, want %v", got, tt.want)
			}
		})
	}
}

func TestVoltController_GetMeterInfo(t *testing.T) {
	type args struct {
		cntx context.Context
		id   uint32
	}
	mtrs := &of.Meter{
		ID:    uint32(256),
		State: 1,
	}
	mtr := map[string]*of.Meter{}
	mtr["SDX6320031"] = mtrs
	devMtr := map[uint32]*of.Meter{}
	devMtr[uint32(256)] = mtrs
	device := &Device{
		ctx:    context.Background(),
		ID:     "SDX6320031",
		meters: devMtr,
	}
	dev := map[string]*Device{}
	dev["SDX6320031"] = device
	tests := []struct {
		name    string
		args    args
		want    map[string]*of.Meter
		wantErr bool
	}{
		{
			name: "VoltController_GetMeterInfo",
			args: args{
				cntx: context.Background(),
				id:   uint32(256),
			},
			want:    mtr,
			wantErr: false,
		},
		{
			name: "Not_Found_Error",
			args: args{
				cntx: context.Background(),
				id:   1,
			},
			want:    nil,
			wantErr: true,
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			v := &VoltController{
				devices: dev,
			}
			switch tt.name {
			case "VoltController_GetMeterInfo":
				got, err := v.GetMeterInfo(tt.args.cntx, tt.args.id)
				if (err != nil) != tt.wantErr {
					t.Errorf("VoltController.GetMeterInfo() error = %v, wantErr %v", err, tt.wantErr)
					return
				}
				if !reflect.DeepEqual(got, tt.want) {
					t.Errorf("VoltController.GetMeterInfo() = %v, want %v", got, tt.want)
				}
			case "Not_Found_Error":
				got, err := v.GetMeterInfo(tt.args.cntx, tt.args.id)
				if (err != nil) != tt.wantErr {
					t.Errorf("VoltController.GetMeterInfo() error = %v, wantErr %v", err, tt.wantErr)
					return
				}
				if !reflect.DeepEqual(got, tt.want) {
					t.Errorf("VoltController.GetMeterInfo() = %v, want %v", got, tt.want)
				}
			}
		})
	}
}

func TestVoltController_GetAllMeterInfo(t *testing.T) {
	vltMtr := map[string][]*of.Meter{}
	mtr := &of.Meter{
		ID:    uint32(256),
		State: 1,
	}
	mtrs := []*of.Meter{}
	mtrs = append(mtrs, mtr)
	vltMtr["SDX6320031"] = mtrs
	devMtr := map[uint32]*of.Meter{}
	devMtr[uint32(256)] = mtr
	device := &Device{
		ctx:    context.Background(),
		ID:     "SDX6320031",
		meters: devMtr,
	}
	dev := map[string]*Device{}
	dev["SDX6320031"] = device
	tests := []struct {
		name    string
		want    map[string][]*of.Meter
		wantErr bool
	}{
		{
			name:    "VoltController_GetMeterInfo",
			want:    vltMtr,
			wantErr: false,
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			v := &VoltController{
				devices: dev,
			}
			got, err := v.GetAllMeterInfo()
			if (err != nil) != tt.wantErr {
				t.Errorf("VoltController.GetAllMeterInfo() error = %v, wantErr %v", err, tt.wantErr)
				return
			}
			if !reflect.DeepEqual(got, tt.want) {
				t.Errorf("VoltController.GetAllMeterInfo() = %v, want %v", got, tt.want)
			}
		})
	}
}

func TestVoltController_GetAllPendingFlows(t *testing.T) {
	subFlowList := []*of.VoltSubFlow{}
	vltSubFlow := &of.VoltSubFlow{
		Priority: 100,
		Cookie:   103112802816,
		State:    of.FlowAddSuccess,
		Match: of.Match{
			InPort:     1573376,
			MatchVlan:  4096,
			L4Protocol: 255,
		},
		Action: of.Action{
			Metadata:    279189651712,
			GoToTableID: 1,
			MeterID:     1,
			SetVlan:     4097,
			Pcp:         8,
			Output:      4,
		},
	}
	subFlowList = append(subFlowList, vltSubFlow)
	subFlows := map[uint64]*of.VoltSubFlow{}
	subFlows[0] = vltSubFlow
	device := &Device{
		ctx:   context.Background(),
		ID:    "SDX6320031",
		flows: subFlows,
	}
	dev := map[string]*Device{}
	dev["SDX6320031"] = device
	tests := []struct {
		name    string
		want    []*of.VoltSubFlow
		wantErr bool
	}{
		{
			name:    "GetAllPendingFlows",
			want:    subFlowList,
			wantErr: false,
		},
	}
	type args1 struct {
		deviceId string
	}
	tests1 := []struct {
		name    string
		args    args1
		want    []*of.VoltSubFlow
		wantErr bool
	}{
		{
			name: "GetFlows_with_DeviceID",
			args: args1{
				deviceId: "SDX6320031",
			},
			want:    subFlowList,
			wantErr: false,
		},
		{
			name: "GetFlows_with_DeviceID_NOT_FOUND",
			args: args1{
				deviceId: "",
			},
			want:    subFlowList,
			wantErr: false,
		},
	}
	type args2 struct {
		deviceId string
		cookie   uint64
	}
	tests2 := []struct {
		name    string
		args    args2
		want    []*of.VoltSubFlow
		wantErr bool
	}{
		{
			name: "GetFlow_with_DeviceID_and_cookie",
			args: args2{
				deviceId: "SDX6320031",
				cookie:   103112802816,
			},
			want:    subFlowList,
			wantErr: false,
		},
		{
			name: "GetFlow_with_DeviceID_and_cookie_NOT_FOUND",
			args: args2{
				deviceId: "",
			},
			want:    subFlowList,
			wantErr: true,
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			v := &VoltController{
				devices: dev,
			}
			got, err := v.GetAllPendingFlows()
			if (err != nil) != tt.wantErr {
				t.Errorf("VoltController.GetAllPendingFlows() error = %v, wantErr %v", err, tt.wantErr)
				return
			}
			assert.Nil(t, got)
			got1, err1 := v.GetAllFlows()
			if (err1 != nil) != tt.wantErr {
				t.Errorf("VoltController.GetAllPendingFlows() error = %v, wantErr %v", err, tt.wantErr)
				return
			}
			assert.NotNil(t, got1)
		})
	}
	for _, tt := range tests1 {
		t.Run(tt.name, func(t *testing.T) {
			v := &VoltController{
				devices: dev,
			}
			switch tt.name {
			case "GetFlows_with_DeviceID":
				got, err := v.GetFlows(tt.args.deviceId)
				if (err != nil) != tt.wantErr {
					t.Errorf("VoltController.GetAllPendingFlows() error = %v, wantErr %v", err, tt.wantErr)
					return
				}
				assert.NotNil(t, got)
			case "GetFlows_with_DeviceID_NOT_FOUND":
				got, err := v.GetFlows(tt.args.deviceId)
				if (err != nil) != tt.wantErr {
					t.Errorf("VoltController.GetAllPendingFlows() error = %v, wantErr %v", err, tt.wantErr)
					return
				}
				assert.Nil(t, got)
			}
		})
	}
	for _, tt := range tests2 {
		t.Run(tt.name, func(t *testing.T) {
			v := &VoltController{
				devices: dev,
			}
			switch tt.name {
			case "GetFlow_with_DeviceID_and_cookie":
				got, err := v.GetFlow(tt.args.deviceId, tt.args.cookie)
				if (err != nil) != tt.wantErr {
					t.Errorf("VoltController.GetAllPendingFlows() error = %v, wantErr %v", err, tt.wantErr)
					return
				}
				assert.Nil(t, got)
			case "GetFlow_with_DeviceID_and_cookie_NOT_FOUND":
				got, err := v.GetFlow(tt.args.deviceId, tt.args.cookie)
				if (err != nil) != tt.wantErr {
					t.Errorf("VoltController.GetAllPendingFlows() error = %v, wantErr %v", err, tt.wantErr)
					return
				}
				assert.Nil(t, got)
			}
		})
	}
}

func TestVoltController_GetTaskList(t *testing.T) {
	type args struct {
		device string
	}
	device := &Device{
		ctx: context.Background(),
		ID:  "SDX6320031",
	}
	dev := map[string]*Device{}
	dev["SDX6320031"] = device
	tests := []struct {
		name string
		args args
		want []tasks.Task
	}{
		{
			name: "GetTaskList",
			args: args{
				device: "SDX6320031",
			},
			want: []tasks.Task{},
		},
		{
			name: "GetTaskList_Device_Not_found",
			args: args{
				device: "SDX632003",
			},
			want: []tasks.Task{},
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			v := &VoltController{
				devices: dev,
			}
			switch tt.name {
			case "GetTaskList":
				if got := v.GetTaskList(tt.args.device); !reflect.DeepEqual(got, tt.want) {
					t.Errorf("VoltController.GetTaskList() = %v, want %v", got, tt.want)
				}
			case "GetTaskList_Device_Not_found":
				if got := v.GetTaskList(tt.args.device); !reflect.DeepEqual(got, tt.want) {
					t.Errorf("VoltController.GetTaskList() = %v, want %v", got, tt.want)
				}
			}
		})
	}
}

func TestVoltController_GetPortState(t *testing.T) {
	type args struct {
		device string
		name   string
	}
	portsByName := map[string]*DevicePort{}
	portsByName["SDX6320031-1"] = &DevicePort{
		Name: "SDX6320031-1",
		ID:   256,
	}
	device := &Device{
		ctx:         context.Background(),
		ID:          "SDX6320031",
		PortsByName: portsByName,
	}
	dev := map[string]*Device{}
	dev["SDX6320031"] = device
	tests := []struct {
		name    string
		args    args
		want    PortState
		wantErr bool
	}{
		{
			name: "GetPortState",
			args: args{
				device: "SDX6320031",
				name:   "SDX6320031-1",
			},
			want: PortStateUp,
		},
		{
			name: "GetPortState_Device_Not_found",
			args: args{
				device: "SDX6320031-1",
				name:   "SDX6320031",
			},
			want:    PortStateDown,
			wantErr: true,
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			v := &VoltController{
				devices: dev,
			}
			switch tt.name {
			case "GetPortState":
				got, err := v.GetPortState(tt.args.device, tt.args.name)
				if (err != nil) != tt.wantErr {
					t.Errorf("VoltController.GetPortState() error = %v, wantErr %v", err, tt.wantErr)
					return
				}
				assert.NotNil(t, got)
			case "GetPortState_Device_Not_found":
				got, err := v.GetPortState(tt.args.device, tt.args.name)
				if (err != nil) != tt.wantErr {
					t.Errorf("VoltController.GetPortState() error = %v, wantErr %v", err, tt.wantErr)
					return
				}
				if got != tt.want {
					t.Errorf("VoltController.GetPortState() = %v, want %v", got, tt.want)
				}
			}
		})
	}
}

func TestVoltController_ModMeter(t *testing.T) {
	type args struct {
		port    string
		device  string
		command of.MeterCommand
		meter   *of.Meter
	}
	portsByName := map[string]*DevicePort{}
	portsByName["SDX6320031-1"] = &DevicePort{
		Name: "SDX6320031-1",
		ID:   256,
	}
	mtrs := &of.Meter{
		ID:    uint32(256),
		State: 1,
	}
	devMtr := map[uint32]*of.Meter{}
	devMtr[uint32(256)] = mtrs
	device := &Device{
		ctx:         context.Background(),
		ID:          "SDX6320031",
		PortsByName: portsByName,
		meters:      devMtr,
	}
	dev := map[string]*Device{}
	dev["SDX6320031"] = device
	tests := []struct {
		name    string
		args    args
		wantErr bool
	}{
		{
			name: "ModMeter",
			args: args{
				device:  "SDX6320031",
				port:    "SDX6320031-1",
				command: of.MeterCommandAdd,
				meter:   mtrs,
			},
			wantErr: false,
		},
		{
			name: "ModMeter_device_not_found",
			args: args{
				command: of.MeterCommandAdd,
				meter:   mtrs,
			},
			wantErr: true,
		},
		{
			name: "ModMeter_port_not_found",
			args: args{
				device:  "SDX6320031",
				command: of.MeterCommandAdd,
				meter:   mtrs,
			},
			wantErr: true,
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			v := &VoltController{
				devices: dev,
			}
			switch tt.name {
			case "ModMeter":
				if err := v.ModMeter(tt.args.port, tt.args.device, tt.args.command, tt.args.meter); (err != nil) != tt.wantErr {
					t.Errorf("VoltController.ModMeter() error = %v, wantErr %v", err, tt.wantErr)
				}
			case "ModMeter_device_not_found":
				if err := v.ModMeter(tt.args.port, tt.args.device, tt.args.command, tt.args.meter); (err != nil) != tt.wantErr {
					t.Errorf("VoltController.ModMeter() error = %v, wantErr %v", err, tt.wantErr)
				}
			case "ModMeter_port_not_found":
				if err := v.ModMeter(tt.args.port, tt.args.device, tt.args.command, tt.args.meter); (err != nil) != tt.wantErr {
					t.Errorf("VoltController.ModMeter() error = %v, wantErr %v", err, tt.wantErr)
				}
			}
		})
	}
}

func TestVoltController_VPAgent(t *testing.T) {
	type args struct {
		vep string
	}
	vagent := map[string]*vpagent.VPAgent{}
	vpa := &vpagent.VPAgent{}
	vagent[""] = vpa
	tests := []struct {
		name    string
		args    args
		want    *vpagent.VPAgent
		wantErr bool
	}{
		{
			name:    "VPAgent",
			args:    args{},
			want:    vpa,
			wantErr: false,
		},
		{
			name: "VPAgent_Error",
			args: args{
				vep: "ab",
			},
			want:    nil,
			wantErr: true,
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			v := &VoltController{
				vagent: vagent,
			}
			switch tt.name {
			case "VPAgent":
				got, err := v.VPAgent(tt.args.vep)
				if (err != nil) != tt.wantErr {
					t.Errorf("VoltController.VPAgent() error = %v, wantErr %v", err, tt.wantErr)
					return
				}
				if !reflect.DeepEqual(got, tt.want) {
					t.Errorf("VoltController.VPAgent() = %v, want %v", got, tt.want)
				}
			case "VPAgent_Error":
				got, err := v.VPAgent(tt.args.vep)
				if (err != nil) != tt.wantErr {
					t.Errorf("VoltController.VPAgent() error = %v, wantErr %v", err, tt.wantErr)
					return
				}
				if !reflect.DeepEqual(got, tt.want) {
					t.Errorf("VoltController.VPAgent() = %v, want %v", got, tt.want)
				}
			}
		})
	}
}

func TestVoltController_DeviceRebootInd(t *testing.T) {
	type args struct {
		cntx context.Context
		dID  string
		srNo string
		sbID string
	}
	appMock := mocks.NewMockApp(gomock.NewController(t))
	NewController(ctx, appMock)
	appMock.EXPECT().DeviceRebootInd(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes()
	dbintf := mocks.NewMockDBIntf(gomock.NewController(t))
	db = dbintf
	dbintf.EXPECT().DelAllRoutesForDevice(gomock.Any(), gomock.Any()).AnyTimes()
	dbintf.EXPECT().DelAllGroup(gomock.Any(), gomock.Any()).AnyTimes()
	dbintf.EXPECT().DelAllMeter(gomock.Any(), gomock.Any()).AnyTimes()
	dbintf.EXPECT().DelAllPONCounters(gomock.Any(), gomock.Any()).AnyTimes()
	tests := []struct {
		name string
		args args
	}{
		{
			name: "VPAgent",
			args: args{
				dID:  "1234",
				srNo: "SDX6320031",
				cntx: context.Background(),
				sbID: "4321",
			},
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			v := &VoltController{
				app: GetController().app,
			}
			v.DeviceRebootInd(tt.args.cntx, tt.args.dID, tt.args.srNo, tt.args.sbID)
		})
	}
}

func TestVoltController_SetRebootInProgressForDevice(t *testing.T) {
	type args struct {
		device string
	}
	rebootInProgressDevices := map[string]string{}
	device := &Device{
		ctx: context.Background(),
		ID:  "SDX6320031",
	}
	dev := map[string]*Device{}
	dev["SDX6320031"] = device
	tests := []struct {
		name string
		args args
		want bool
	}{
		{
			name: "SetRebootInProgressForDevice",
			args: args{
				device: "SDX6320031",
			},
			want: true,
		},
		{
			name: "SetRebootInProgressForDevice_Error",
			args: args{
				device: "SDX6320031-1",
			},
			want: true,
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			v := &VoltController{
				rebootInProgressDevices: rebootInProgressDevices,
				devices:                 dev,
			}
			switch tt.name {
			case "SetRebootInProgressForDevice":
				if got := v.SetRebootInProgressForDevice(tt.args.device); got != tt.want {
					t.Errorf("VoltController.SetRebootInProgressForDevice() = %v, want %v", got, tt.want)
				}
			case "SetRebootInProgressForDevice_Error":
				if got := v.SetRebootInProgressForDevice(tt.args.device); got != tt.want {
					t.Errorf("VoltController.SetRebootInProgressForDevice() = %v, want %v", got, tt.want)
				}
			}
		})
	}
}

func TestVoltController_ReSetRebootInProgressForDevice(t *testing.T) {
	type args struct {
		device string
	}
	rebootInProgressDevices := map[string]string{}
	device := &Device{
		ctx: context.Background(),
		ID:  "SDX6320031",
	}
	rebootInProgressDevices["SDX6320031"] = "done"
	dev := map[string]*Device{}
	dev["SDX6320031"] = device
	tests := []struct {
		name string
		args args
		want bool
	}{
		{
			name: "ReSetRebootInProgressForDevice",
			args: args{
				device: "SDX6320031",
			},
			want: true,
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			v := &VoltController{
				rebootInProgressDevices: rebootInProgressDevices,
				devices:                 dev,
			}
			if got := v.ReSetRebootInProgressForDevice(tt.args.device); got != tt.want {
				t.Errorf("VoltController.ReSetRebootInProgressForDevice() = %v, want %v", got, tt.want)
			}
		})
	}
}
