/*
 * 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.Debug("Omci msg type not handled: %d", msgType)
		}

		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
}
