/*
 * Copyright 2020-2024 Open Networking Foundation (ONF) and the ONF Contributors
 *
 * 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 common provides global definitions
package common

import (
	"bytes"
	"context"
	"encoding/binary"
	"errors"
	"fmt"
	"net"
	"regexp"
	"strconv"
	"strings"
	"time"

	"github.com/looplab/fsm"
	me "github.com/opencord/omci-lib-go/v2/generated"
	"github.com/opencord/voltha-lib-go/v7/pkg/log"
)

// GetTpIDFromTpPath extracts TpID from the TpPath.
// On success it returns a valid TpID and nil error.
// On failure it returns TpID as 0 and the error.
func GetTpIDFromTpPath(tpPath string) (uint8, error) {
	// tpPath is of the format  <technology>/<table_id>/olt-{}/pon-{}/onu-{}/uni-{}
	// A sample tpPath is ==> XGS-PON/64/olt-{12345abcd}/pon-{0}/onu-{1}/uni-{1}
	var tpPathFormat = regexp.MustCompile(`^[a-zA-Z\-_]+/[0-9]+/olt-{[a-z0-9\-]+}/pon-{[0-9]+}/onu-{[0-9]+}/uni-{[0-9]+}$`)

	// Ensure tpPath is of the format  <technology>/<table_id>/<uni_port_name>
	if !tpPathFormat.Match([]byte(tpPath)) {
		return 0, errors.New("tp-path-not-confirming-to-format")
	}
	// Extract the TP table-id field.
	tpID, err := strconv.Atoi(strings.Split(tpPath, "/")[1])
	// Atoi returns uint64 and need to be type-casted to uint8 as tpID is uint8 size.
	return uint8(tpID), err
}

// IPToInt32 transforms an IP of net.Ip type to int32
func IPToInt32(ip net.IP) uint32 {
	if len(ip) == 16 {
		return binary.BigEndian.Uint32(ip[12:16])
	}
	return binary.BigEndian.Uint32(ip)
}

// AsByteSlice transforms a string of manually set bits to a byt array
func AsByteSlice(bitString string) []byte {
	var out []byte
	var str string

	for i := len(bitString); i > 0; i -= 8 {
		if i-8 < 0 {
			str = bitString[0:i]
		} else {
			str = bitString[i-8 : i]
		}
		v, err := strconv.ParseUint(str, 2, 8)
		if err != nil {
			panic(err)
		}
		out = append([]byte{byte(v)}, out...)
	}
	return out
}

// TwosComplementToSignedInt16 convert 2s complement to signed int16
func TwosComplementToSignedInt16(val uint16) int16 {
	var uint16MsbMask uint16 = 0x8000
	if val&uint16MsbMask == uint16MsbMask {
		return int16(^val+1) * -1
	}

	return int16(val)
}

// TrimStringFromMeOctet trim string out of Me octet
func TrimStringFromMeOctet(input interface{}) string {
	ifBytes, _ := me.InterfaceToOctets(input)
	return fmt.Sprintf("%s", bytes.Trim(ifBytes, "\x00"))
}

////////////////////////////////////////////////////////////////////////

// NewAdapterFsm - FSM details including event, device and channel.
func NewAdapterFsm(aName string, aDeviceID string, aCommChannel chan Message) *AdapterFsm {
	aFsm := &AdapterFsm{
		fsmName:  aName,
		deviceID: aDeviceID,
		CommChan: aCommChannel,
	}
	return aFsm
}

// LogFsmStateChange logs FSM state changes
func (oo *AdapterFsm) LogFsmStateChange(ctx context.Context, e *fsm.Event) {
	logger.Debugw(ctx, "FSM state change", log.Fields{"device-id": oo.deviceID, "FSM name": oo.fsmName,
		"event name": string(e.Event), "src state": string(e.Src), "dst state": string(e.Dst)})
}

////////////////////////////////////////////////////////////////////////

// GenerateIeeMaperServiceProfileEID returns IeeMaperServiceProfileEntityID
func GenerateIeeMaperServiceProfileEID(uniPortMacBpNo uint16, tpID uint16) (uint16, error) {
	if tpID < tpIDStart || tpID >= tpIDEnd {
		return 0, fmt.Errorf("tech profile id out of range - %d", tpID)
	}
	if uniPortMacBpNo > maxUni {
		return 0, fmt.Errorf("uni macbpno out of range - %d", uniPortMacBpNo)
	}
	return (IeeMaperServiceProfileBaseEID + uniPortMacBpNo*tpRange + tpID - tpIDStart), nil
}

// GenerateANISideMBPCDEID returns ANISideMacBridgePortConfigurationDataEntryID
func GenerateANISideMBPCDEID(uniPortMacBpNo uint16, tpID uint16) (uint16, error) {
	if tpID < tpIDStart || tpID >= tpIDEnd {
		return 0, fmt.Errorf("tech profile id out of range - %d", tpID)
	}
	if uniPortMacBpNo > maxUni {
		return 0, fmt.Errorf("uni macbpno out of range - %d", uniPortMacBpNo)
	}
	return (MacBridgePortAniBaseEID + uniPortMacBpNo*tpRange + tpID - tpIDStart), nil
}

// GenerateUNISideMBPCDEID returns UNISideMacBridgePortConfigurationDataEntityID
func GenerateUNISideMBPCDEID(uniPortMacBpNo uint16) (uint16, error) {
	if uniPortMacBpNo > maxUni {
		return 0, fmt.Errorf("uni macbpno out of range - %d", uniPortMacBpNo)
	}
	return (MacBridgePortUniBaseEID + uniPortMacBpNo), nil
}

// GenerateMcastANISideMBPCDEID returns McastANISideMacBridgePortConfigurationDataEntityID
func GenerateMcastANISideMBPCDEID(uniPortMacBpNo uint16) (uint16, error) {

	if uniPortMacBpNo > maxUni {
		return 0, fmt.Errorf("uni macbpno out of range - %d", uniPortMacBpNo)
	}
	return (MacBridgePortAniMcastBaseEID + uniPortMacBpNo), nil
}

// GenerateVoipUNISideMEID return VoipUNISideMEEntityID
func GenerateVoipUNISideMEID(uniPortMacBpNo uint16) (uint16, error) {
	if uniPortMacBpNo > maxUni {
		return 0, fmt.Errorf("uni macbpno out of range - %d", uniPortMacBpNo)
	}
	return (VoipUniBaseEID + uniPortMacBpNo), nil
}

// WaitTimeout of waitGroupWithTimeOut is blocking
//
//	returns true, if the wg request was executed successfully, false on timeout
func (wg *WaitGroupWithTimeOut) WaitTimeout(timeout time.Duration) bool {
	done := make(chan struct{})

	go func() {
		defer close(done)
		wg.Wait()
	}()

	select {
	case <-done:
		return true

	case <-time.After(timeout):
		return false
	}
}
