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

import (
	"gerrit.opencord.org/voltha-bbsim/common/logger"
)

type OmciMsg struct {
	IntfId uint32
	OnuId  uint32
	Pkt    []byte
}

const NumMibUploads byte = 9

type OnuKey struct {
	IntfId, OnuId uint32
}

type OnuState struct {
	mibUploadCtr uint16
	uniGInstance uint8
	pptpInstance uint8
}

func OmciRun(omciOut chan OmciMsg, omciIn chan OmciMsg) {

	onus := make(map[OnuKey]*OnuState)

	for {
		var resp OmciMsg

		m := <-omciOut

		msgType, transactionId, meClass, meInstance := ParsePkt(m.Pkt)

		logger.Debug("OmciRun - transactionId: %d msgType: %d, ME Class: %d, ME Instance: %d",
			transactionId, msgType, meClass, meInstance)

		key := OnuKey{m.IntfId, m.OnuId}
		if _, ok := onus[key]; !ok {
			onus[key] = NewOnuState()
		}
		switch msgType {
		case 15:
			resp.Pkt = MibReset()
		case 13:
			resp.Pkt = MibUpload()
		case 14:
			resp.Pkt = MibUploadNext(onus[key])
		case 8:
			resp.Pkt = Set()
		case 4:
			resp.Pkt = Create()
		case 9:
			resp.Pkt = Get()
		default:
			logger.Warn("Omci msg type not handled: %d", msgType)
			continue
		}

		resp.Pkt[0] = byte(transactionId >> 8)
		resp.Pkt[1] = byte(transactionId & 0xFF)
		resp.IntfId = m.IntfId
		resp.OnuId = m.OnuId
		omciIn <- resp
	}
}

func ParsePkt(pkt []byte) (byte, uint16, uint16, uint16) {
	p := make([]byte, len(pkt)/2)
	for i, j := 0, 0; i < len(pkt); i, j = i+2, j+1 {
		u := (pkt[i] & 15) + (pkt[i]>>6)*9
		l := (pkt[i+1] & 15) + (pkt[i+1]>>6)*9
		p[j] = u<<4 + l
	}
	logger.Debug("Omci decoded: %x.", p)
	msgType := p[2] & 0x0F
	transactionId := (uint16(p[0]) << 8) | uint16(p[1])
	meClass := (uint16(p[4]) << 8) | uint16(p[5])
	meInstance := (uint16(p[6]) << 8) | uint16(p[7])
	return msgType, transactionId, meClass, meInstance
}

func NewOnuState() *OnuState {
	return &OnuState{mibUploadCtr: 0, uniGInstance: 1, pptpInstance: 1}
}

func MibReset() []byte {
	var pkt []byte

	logger.Debug("Omci MibReset")

	pkt = []byte{
		0x00, 0x01, 0x2f, 0x0a, 0x00, 0x02, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x28, 0x1f, 0x75, 0x69, 0xaa}
	return pkt
}

func MibUpload() []byte {
	var pkt []byte

	logger.Debug("Omci MibUpload")

	pkt = []byte{
		0x00, 0x02, 0x2d, 0x0a, 0x00, 0x02, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x28, 0x0c, 0x63, 0x21, 0x65}

	pkt[9] = NumMibUploads // Number of subsequent MibUploadNext cmds

	return pkt
}

func MibUploadNext(state *OnuState) []byte {
	var pkt []byte

	logger.Debug("Omci MibUploadNext")

	switch state.mibUploadCtr {
	case 0:
		// ANI-G
		pkt = []byte{
			0x00, 0x03, 0x2e, 0x0a, 0x00, 0x02, 0x00, 0x00,
			0x01, 0x07, 0x80, 0x01, 0xff, 0xff, 0x01, 0x00,
			0x08, 0x00, 0x30, 0x00, 0x00, 0x05, 0x09, 0x00,
			0x00, 0xe0, 0x54, 0xff, 0xff, 0x00, 0x00, 0x0c,
			0x63, 0x81, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00,
			0x00, 0x00, 0x00, 0x28, 0x2c, 0x4d, 0xa9, 0xc8}
	case 1, 2, 3, 4:
		// UNI-G
		pkt = []byte{
			0x00, 0x04, 0x2e, 0x0a, 0x00, 0x02, 0x00, 0x00,
			0x01, 0x08, 0x01, 0x01, 0xf8, 0x00, 0x00, 0x00,
			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
			0x00, 0x00, 0x00, 0x28, 0x05, 0x19, 0xae, 0x66}
		pkt[11] = state.uniGInstance // ME Instance
		state.uniGInstance++
	case 5, 6, 7, 8:
		pkt = []byte{
			0x00, 0x16, 0x2e, 0x0a, 0x00, 0x02, 0x00, 0x00,
			0x00, 0x0b, 0x01, 0x01, 0xff, 0xfe, 0x00, 0x2f,
			0x00, 0x00, 0x00, 0x00, 0x03, 0x05, 0xee, 0x00,
			0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
			0x00, 0x00, 0x00, 0x28, 0x6f, 0x10, 0x9b, 0x27}
		pkt[11] = state.pptpInstance // ME Instance
		state.pptpInstance++
	default:
		logger.Error("Invalid MibUpload request %d", state.mibUploadCtr)
	}

	state.mibUploadCtr++

	return pkt
}

func Set() []byte {
	var pkt []byte

	pkt = []byte{
		0x01, 0x15, 0x28, 0x0a, 0x01, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x28, 0x41, 0xb3, 0x95, 0x12}

	logger.Debug("Omci Set")

	return pkt
}

func Create() []byte {
	var pkt []byte

	pkt = []byte{
		0x01, 0x17, 0x24, 0x0a, 0x01, 0x10, 0x00, 0x01,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x28, 0x85, 0xcb, 0x98, 0x86}

	logger.Debug("Omci Create")

	return pkt
}

func Get() []byte {
	var pkt []byte

	pkt = []byte{
		0x01, 0x26, 0x29, 0x0a, 0x00, 0x2d, 0x02, 0x01,
		0x00, 0x20, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x28, 0xbc, 0x0c, 0xa4, 0x18}

	logger.Debug("Omci Get")

	return pkt
}
