/*
* 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 util

import (
	"encoding/binary"
	"net"
	"strings"

	"voltha-go-controller/internal/pkg/of"
)

// RemoveFromSlice to remove particular value from given slice.
func RemoveFromSlice(s []string, value string) []string {
	i := 0
	for i = 0; i < len(s); i++ {
		if s[i] == value {
			break
		}
	}
	if i != len(s) {
		//It means value is found in the slice
		s[len(s)-1], s[i] = s[i], s[len(s)-1]
		return s[:len(s)-1]
	}
	return s
}

//IsSliceSame - check and return true if the two slices are identical
func IsSliceSame(ref, rcvd []uint32) bool {

	var found bool
	if len(ref) != len(rcvd) {
		return false
	}

	for _, refEntry := range ref {
		found = false

		for _, rcvdEntry := range rcvd {
			if refEntry == rcvdEntry {
				found = true
				break
			}
		}
		if !found {
			return false
		}
	}
	return true
}

//IsPbitSliceSame - check and return true if the two slices are identical
func IsPbitSliceSame(ref, rcvd []of.PbitType) bool {

	var found bool
	if len(ref) != len(rcvd) {
		return false
	}

	for _, refEntry := range ref {
		found = false

		for _, rcvdEntry := range rcvd {
			if refEntry == rcvdEntry {
				found = true
				break
			}
		}
		if !found {
			return false
		}
	}
	return true
}

// IsNniPort is to check if given port is Nni Port.
func IsNniPort(id uint32) bool {
	return (id >= 0x100000)
}

// Uint32ToByte to convert uint32 to byte
func Uint32ToByte(value uint32) []byte {
	byteValue := make([]byte, 4)
	binary.BigEndian.PutUint32(byteValue[0:4], value)
	return byteValue
}

// IP2LongConv convert ip address to integer value.
func IP2LongConv(ip net.IP) uint32 {
	if len(ip) == 16 {
		return binary.BigEndian.Uint32(ip[12:16])
	}
	return binary.BigEndian.Uint32(ip)
}

// Long2ipConv convert integer to ip address.
func Long2ipConv(nn uint32) net.IP {
	ip := make(net.IP, 4)
	binary.BigEndian.PutUint32(ip, nn)
	return ip
}

// GetExpIPList converts list or range of IPs to expanded IP list
func GetExpIPList(ips []string) []net.IP {
	ipList := []net.IP{}

	for _, ipOrRange := range ips {
		if strings.Contains(ipOrRange, "-") {
			var splits = strings.Split(ipOrRange, "-")
			ipStart := IP2LongConv(net.ParseIP(splits[0]))
			ipEnd := IP2LongConv(net.ParseIP(splits[1]))

			for i := ipStart; i <= ipEnd; i++ {
				ipList = append(ipList, Long2ipConv(i))
			}
		} else {
			ipList = append(ipList, net.ParseIP(ipOrRange))
		}
	}
	return ipList
}

// MacAddrsMatch for comparison of MAC addresses and return true if MAC addresses matches
func MacAddrsMatch(addr1 net.HardwareAddr, addr2 net.HardwareAddr) bool {
	if len(addr1) != len(addr2) {
		return false
	}
	for i := 0; i < len(addr1); i++ {
		if addr1[i] != addr2[i] {
			return false
		}
	}
	return true
}
