/*
 * Copyright 2018-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 devices

import (
	"context"
	"github.com/opencord/bbsim/internal/bbsim/types"
	"github.com/opencord/bbsim/internal/common"
	"github.com/opencord/voltha-protos/v3/go/openolt"
	"github.com/stretchr/testify/assert"
	"net"
	"testing"
	"time"
)

type mockService struct {
	Name                   string
	HandleAuthCallCount    int
	HandleDhcpCallCount    int
	HandlePacketsCallCount int
}

func (s *mockService) HandleAuth() {
	s.HandleAuthCallCount = s.HandleAuthCallCount + 1
}

func (s *mockService) HandleDhcp(pbit uint8, cTag int) {
	s.HandleDhcpCallCount = s.HandleDhcpCallCount + 1
}

func (s *mockService) HandlePackets() {
	s.HandlePacketsCallCount = s.HandlePacketsCallCount + 1
}

func (s *mockService) Initialize(stream types.Stream) {}
func (s *mockService) Disable()                       {}

func createTestService(needsEapol bool, needsDchp bool) (*Service, error) {

	enableContext := context.TODO()

	mac := net.HardwareAddr{0x2e, 0x60, byte(1), byte(1), byte(1), byte(1)}
	onu := createMockOnu(1, 1)
	onu.PonPort = &PonPort{}
	onu.PonPort.Olt = &OltDevice{}
	onu.PonPort.Olt.enableContext = enableContext
	return NewService("testService", mac, onu, 900, 900,
		needsEapol, needsDchp, false, 64, 0, false,
		7, 7, 7, 7)
}

// test the internalState transitions
func TestService_InternalState(t *testing.T) {
	s, err := createTestService(false, false)

	assert.Nil(t, err)

	assert.Empty(t, s.PacketCh)
	s.Initialize(&mockStream{})

	// check that channels have been created
	assert.NotNil(t, s.PacketCh)
	assert.NotNil(t, s.Channel)

	// set EAPOL and DHCP states to something else
	s.EapolState.SetState("eap_response_success_received")
	s.DHCPState.SetState("dhcp_ack_received")

	s.Disable()
	// make sure the EAPOL and DHCP states have been reset after disable
	assert.Equal(t, "created", s.EapolState.Current())
	assert.Equal(t, "created", s.DHCPState.Current())

	// make sure the channel have been closed
	assert.Nil(t, s.Channel)
	assert.Nil(t, s.PacketCh)
}

// make sure that if the service does not need EAPOL we're not sending any packet
func TestService_HandleAuth_noEapol(t *testing.T) {
	s, err := createTestService(false, false)

	assert.Nil(t, err)

	stream := &mockStream{
		Calls:   make(map[int]*openolt.Indication),
		channel: make(chan int, 10),
	}
	s.Initialize(stream)

	s.HandleAuth()
	time.Sleep(1 * time.Second)

	// if the service does not need EAPOL we don't expect any packet to be generated
	assert.Equal(t, stream.CallCount, 0)

	// state should not change
	assert.Equal(t, s.EapolState.Current(), "created")
}

// make sure that if the service does need EAPOL we're sending any packet
func TestService_HandleAuth_withEapol(t *testing.T) {
	s, err := createTestService(true, false)

	assert.Nil(t, err)

	stream := &mockStream{
		Calls: make(map[int]*openolt.Indication),
	}
	s.Initialize(stream)

	s.HandleAuth()
	time.Sleep(1 * time.Second)

	// if the service does not need EAPOL we don't expect any packet to be generated
	assert.Equal(t, stream.CallCount, 1)

	// state should not change
	assert.Equal(t, s.EapolState.Current(), "eap_start_sent")
}

// make sure that if the service does not need DHCP we're not sending any packet
func TestService_HandleDhcp_not_needed(t *testing.T) {
	s, err := createTestService(false, false)

	assert.Nil(t, err)

	stream := &mockStream{
		Calls: make(map[int]*openolt.Indication),
	}
	s.Initialize(stream)

	s.HandleDhcp(7, 900)
	time.Sleep(1 * time.Second)

	assert.Equal(t, stream.CallCount, 0)

	// state should not change
	assert.Equal(t, s.DHCPState.Current(), "created")
}

// when we receive a DHCP flow we call HandleDhcp an all the ONU Services
// each service device whether the tag matches it's own configuration
func TestService_HandleDhcp_different_c_Tag(t *testing.T) {
	s, err := createTestService(false, true)

	assert.Nil(t, err)

	stream := &mockStream{
		Calls: make(map[int]*openolt.Indication),
	}
	s.Initialize(stream)

	// NOTE that the c_tag is different from the one configured in the service
	s.HandleDhcp(7, 800)
	time.Sleep(1 * time.Second)

	assert.Equal(t, stream.CallCount, 0)

	// state should not change
	assert.Equal(t, s.DHCPState.Current(), "created")
}

// when we receive a DHCP flow we call HandleDhcp an all the ONU Services
// each service device whether the tag matches it's own configuration
func TestService_HandleDhcp_different_pbit(t *testing.T) {
	s, err := createTestService(false, true)

	assert.Nil(t, err)

	stream := &mockStream{
		Calls: make(map[int]*openolt.Indication),
	}
	s.Initialize(stream)

	// NOTE that the c_tag is different from the one configured in the service
	s.HandleDhcp(5, 900)
	time.Sleep(1 * time.Second)

	assert.Equal(t, stream.CallCount, 0)

	// state should not change
	assert.Equal(t, s.DHCPState.Current(), "created")
}

// if PBIT is 255 it means all of them, so start DHCP if the C_TAG matches
func TestService_HandleDhcp_pbit_255(t *testing.T) {
	s, err := createTestService(false, true)

	assert.Nil(t, err)

	stream := &mockStream{
		Calls: make(map[int]*openolt.Indication),
	}
	s.Initialize(stream)

	// NOTE that the c_tag is different from the one configured in the service
	s.HandleDhcp(255, 900)
	time.Sleep(1 * time.Second)

	assert.Equal(t, 1, stream.CallCount)
	assert.Equal(t, s.DHCPState.Current(), "dhcp_discovery_sent")
}

// make sure that if the service does need DHCP we're sending any packet
func TestService_HandleDhcp_needed(t *testing.T) {
	s, err := createTestService(false, true)

	assert.Nil(t, err)

	stream := &mockStream{
		Calls: make(map[int]*openolt.Indication),
	}
	s.Initialize(stream)

	s.HandleDhcp(7, 900)
	time.Sleep(1 * time.Second)

	assert.Equal(t, 1, stream.CallCount)
	assert.Equal(t, "dhcp_discovery_sent", s.DHCPState.Current())
}

// Test that if the EAPOL state machine doesn't complete in 30 seconds we
// move it to EAPOL failed
func TestService_EAPOLFailed(t *testing.T) {

	common.Config = &common.GlobalConfig{
		BBSim: common.BBSimConfig{
			AuthRetry: false,
		},
	}

	// override the default wait time
	eapolWaitTime = 500 * time.Millisecond
	s, err := createTestService(true, false)

	assert.Nil(t, err)

	stream := &mockStream{
		Calls: make(map[int]*openolt.Indication),
	}
	s.Initialize(stream)

	// set to failed if timeout occurs
	_ = s.EapolState.Event("start_auth")
	time.Sleep(1 * time.Second)
	assert.Equal(t, "auth_failed", s.EapolState.Current())

	// do not set to failed if succeeded
	s.EapolState.SetState("created")
	_ = s.EapolState.Event("start_auth")
	s.EapolState.SetState("eap_response_success_received")
	time.Sleep(1 * time.Second)
	assert.Equal(t, "eap_response_success_received", s.EapolState.Current())

}

func TestService_EAPOLRestart(t *testing.T) {

	common.Config = &common.GlobalConfig{
		BBSim: common.BBSimConfig{
			AuthRetry: true,
		},
	}

	eapolWaitTime = 500 * time.Millisecond
	s, err := createTestService(true, false)

	assert.Nil(t, err)

	stream := &mockStream{
		Calls: make(map[int]*openolt.Indication),
	}
	s.Initialize(stream)

	// set to failed if timeout occurs
	_ = s.EapolState.Event("start_auth")

	// after a second EAPOL should have failed and restarted
	time.Sleep(1 * time.Second)
	assert.Equal(t, "eap_start_sent", s.EapolState.Current())
}

// Test that if the DHCP state machine doesn't complete in 30 seconds we
// move it to DHCP failed
func TestService_DHCPFailed(t *testing.T) {

	common.Config = &common.GlobalConfig{
		BBSim: common.BBSimConfig{
			DhcpRetry: false,
		},
	}

	// override the default wait time
	dhcpWaitTime = 100 * time.Millisecond
	s, err := createTestService(false, true)

	assert.Nil(t, err)

	stream := &mockStream{
		Calls: make(map[int]*openolt.Indication),
	}
	s.Initialize(stream)

	// set to failed if timeout occurs
	_ = s.DHCPState.Event("start_dhcp")
	time.Sleep(1 * time.Second)
	assert.Equal(t, "dhcp_failed", s.DHCPState.Current())

	// do not set to failed if succeeded
	s.DHCPState.SetState("created")
	_ = s.DHCPState.Event("start_dhcp")
	s.DHCPState.SetState("dhcp_ack_received")
	time.Sleep(1 * time.Second)
	assert.Equal(t, "dhcp_ack_received", s.DHCPState.Current())
}

func TestService_DHCPRestart(t *testing.T) {
	common.Config = &common.GlobalConfig{
		BBSim: common.BBSimConfig{
			DhcpRetry: true,
		},
	}

	// override the default wait time
	dhcpWaitTime = 100 * time.Millisecond
	s, err := createTestService(false, true)

	assert.Nil(t, err)

	stream := &mockStream{
		Calls: make(map[int]*openolt.Indication),
	}
	s.Initialize(stream)

	// set to failed if timeout occurs
	_ = s.DHCPState.Event("start_dhcp")
	time.Sleep(1 * time.Second)
	assert.Equal(t, "dhcp_discovery_sent", s.DHCPState.Current())
}
