/*
 * 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 (
	"encoding/binary"
	"errors"
	"fmt"
	log "github.com/sirupsen/logrus"
)

type OmciMsgHandler func(class OmciClass, content OmciContent, key OnuKey) ([]byte, error)

var Handlers = map[OmciMsgType]OmciMsgHandler{
	MibReset:         mibReset,
	MibUpload:        mibUpload,
	MibUploadNext:    mibUploadNext,
	Set:              set,
	Create:           create,
	Get:              get,
	GetAllAlarms:     getAllAlarms,
	GetAllAlarmsNext: getAllAlarmsNext,
	SynchronizeTime:  syncTime,
	Delete:           delete,
	Reboot:           reboot,
	Test: testHandler,
}

func mibReset(class OmciClass, content OmciContent, key OnuKey) ([]byte, error) {
	var pkt []byte

	log.WithFields(log.Fields{
		"IntfId": key.IntfId,
		"OnuId": key.OnuId,
	}).Tracef("Omci MibReset")
	OnuOmciStateMapLock.RLock()
	if state, ok := OnuOmciStateMap[key]; ok {
		log.WithFields(log.Fields{
		"IntfId": key.IntfId,
		"OnuId": key.OnuId,
	}).Tracef("Reseting OnuOmciState")
		state.ResetOnuOmciState()
	}
	OnuOmciStateMapLock.RUnlock()

	pkt = []byte{
		0x00, 0x00, 0x00, 0x00, 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, 0x00, 0x00, 0x00, 0x00, 0x00}
	return pkt, nil
}

func mibUpload(class OmciClass, content OmciContent, key OnuKey) ([]byte, error) {
	var pkt []byte

	log.WithFields(log.Fields{
		"IntfId": key.IntfId,
		"OnuId": key.OnuId,
	}).Tracef("Omci MibUpload")

	pkt = []byte{
		0x00, 0x00, 0x00, 0x00, 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, 0x00, 0x00, 0x00, 0x00, 0x00}

	pkt[8] = NumMibUploadsHigherByte
	pkt[9] = NumMibUploadsLowerByte

	return pkt, nil
}

func mibUploadNext(class OmciClass, content OmciContent, key OnuKey) ([]byte, error) {
	var pkt []byte
	OnuOmciStateMapLock.RLock()
	state := OnuOmciStateMap[key]
	OnuOmciStateMapLock.RUnlock()
	// commandNumber is the "Command number" attribute received in "MIB Upload Next" OMCI message
	commandNumber := (uint16(content[1])) | (uint16(content[0])<<8)
	log.WithFields(log.Fields{
		"IntfId": key.IntfId,
		"OnuId": key.OnuId,
		"CommandNumber": commandNumber,
	}).Tracef("Omci MibUploadNext")

	switch commandNumber {
	case 0:
		// ONT Data (2)
		// log.Println("ONT DATA")
		pkt = []byte{
			0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
			0x00, 0x02, 0x00, 0x00, 0x80, 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}
	case 1:
		// Circuit Pack (6) - #1
		// log.Println("Circuit Pack")
		pkt = []byte{
			0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
			0x00, 0x06, 0x01, 0x01, 0xf0, 0x00, 0x2f, 0x04,
			0x49, 0x53, 0x4b, 0x54, 0x71, 0xe8, 0x00, 0x80,
			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
			0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00,
			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
	case 2:
		// Circuit Pack (6) - #2
		// log.Println("Circuit Pack")
		pkt = []byte{
			0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
			0x00, 0x06, 0x01, 0x01, 0x0f, 0x00, 0x42, 0x52,
			0x43, 0x4d, 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}
	case 3:
		// Circuit Pack (6) - #3
		// log.Println("Circuit Pack")
		pkt = []byte{
			0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
			0x00, 0x06, 0x01, 0x01, 0x00, 0xf8, 0x20, 0x20,
			0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
			0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
			0x20, 0x20, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
	case 4:
		// Circuit Pack (6) - #4
		// log.Println("Circuit Pack")
		pkt = []byte{
			0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
			0x00, 0x06, 0x01, 0x01, 0x00, 0x04, 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}
	case 5:
		// Circuit Pack (6) - #5
		// log.Println("Circuit Pack")
		pkt = []byte{
			0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
			0x00, 0x06, 0x01, 0x80, 0xf0, 0x00, 0xee, 0x01,
			0x49, 0x53, 0x4b, 0x54, 0x71, 0xe8, 0x00, 0x80,
			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
			0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00,
			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
	case 6:
		// Circuit Pack (6) - #6
		// log.Println("Circuit Pack")
		pkt = []byte{
			0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
			0x00, 0x06, 0x01, 0x80, 0x0f, 0x00, 0x42, 0x52,
			0x43, 0x4d, 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}
	case 7:
		// Circuit Pack (6) - #7
		// log.Println("Circuit Pack")
		pkt = []byte{
			0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
			0x00, 0x06, 0x01, 0x80, 0x00, 0xf8, 0x20, 0x20,
			0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
			0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
			0x20, 0x20, 0x00, 0x08, 0x40, 0x10, 0x00, 0x00,
			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
	case 8:
		// Circuit Pack (6) - #8
		// log.Println("Circuit Pack")
		pkt = []byte{
			0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
			0x00, 0x06, 0x01, 0x80, 0x00, 0x04, 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}
	case 9, 10, 11, 12:
		// PPTP (11)
		// log.Println("PPTP")
		pkt = []byte{
			0x00, 0x00, 0x00, 0x00, 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, 0x00, 0x00, 0x00, 0x00, 0x00}
		pkt[11] = state.pptpInstance // ME Instance
		state.pptpInstance++
	case 13, 14, 15, 16, 17, 18, 19, 20:
		// T-CONT (262)
		// log.Println("T-CONT")
		pkt = []byte{
			0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
			0x01, 0x06, 0x80, 0x00, 0xe0, 0x00, 0xff, 0xff,
			0x01, 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}

		state.tcontInstance++
		pkt[11] = state.tcontInstance // TCONT ME Instance

	case 21:
		// ANI-G (263)
		// log.Println("ANI-G")
		pkt = []byte{
			0x00, 0x00, 0x00, 0x00, 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, 0x00, 0x00, 0x00, 0x00, 0x00}
	case 22, 23, 24, 25:
		// UNI-G (264)
		// log.Println("UNI-G")
		pkt = []byte{
			0x00, 0x00, 0x00, 0x00, 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, 0x00, 0x00, 0x00, 0x00, 0x00}
		pkt[11] = state.uniGInstance // UNI-G ME Instance
		state.uniGInstance++

	case 26,  30,  34,  38,  42, 46, 50, 54,
	     58,  62,  66,  70,  74, 78, 82, 86,
	     90,  94,  98,  102, 106, 110, 114, 118,
	     122, 126, 130, 134, 138, 142, 146, 150,
	     154, 158, 162, 166, 170, 174, 178, 182,
	     186, 190, 194, 198, 202, 206, 210, 214,
	     218, 222, 226, 230, 234, 238, 242, 246,
	     250, 254, 258, 262, 266, 270, 274, 278:
		// Prior-Q with mask downstream
		log.Tracef("Mib-upload for prior-q with mask")
		// For downstream PQ, pkt[10] is 0x00
		// So the instanceId will be like 0x0001, 0x0002,... etc
		pkt = []byte{
			0x00, 0x42, 0x2e, 0x0a, 0x00, 0x02, 0x00, 0x00,
			0x01, 0x15, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff,
			0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
			0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		}
		state.priorQInstance++
		pkt[11] = state.priorQInstance

	case 27,  31,  35,  39,  43,  47, 51, 55,
	     59,  63,  67,  71,  75,  79, 83, 87,
	     91,  95,  99,  103, 107, 111, 115, 119,
	     123, 127, 131, 135, 139, 143, 147, 151,
	     155, 159, 163, 167, 171, 175, 179, 183,
	     187, 191, 195, 199, 203, 207, 211, 215,
	     219, 223, 227, 231, 235, 239, 243, 247,
	     251, 255, 259, 263, 267, 271, 275, 279:
		// Prior-Q with attribute list downstream
		// log.Println("Mib-upload for prior-q with attribute list")
		pkt = []byte{
			0x00, 0x43, 0x2e, 0x0a, 0x00, 0x02, 0x00, 0x00,
			0x01, 0x15, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x01,
			0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
			0x20, 0x00, 0x00, 0x01, 0x20, 0x01, 0x00, 0x01,
			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		}

		pkt[11] = state.priorQInstance

		// Group 8 PriorQ to point to a particular TCONT
		// Priority for each group of PriorQ is 0 - 7
		if state.priorQPriority % NumPriorQPerTcont == 0 {
			state.tcontPointer++
		}

		// Only for verification. To be removed
		if state.tcontPointer > state.tcontInstance {
			log.Tracef("Error: Invalid TcontPointer")
			break
		}

		pkt[24] = state.tcontPointer
		pkt[26] = state.priorQPriority % NumPriorQPerTcont
		pkt[28] = state.tcontInstance

	case 28,  32,  36,  40,  44, 48, 52, 56,
	     60,  64,  68,  72,  76, 80, 84, 88,
	     92,  96,  100, 104, 108, 112, 116, 120,
	     124, 128, 132, 136, 140, 144, 148, 152,
	     156, 160, 164, 168, 172, 176, 180, 184,
	     188, 192, 196, 200, 204, 208, 212, 216,
	     220, 224, 228, 232, 236, 240, 244, 248,
	     252, 256, 260, 264, 268, 272, 276, 280:
		// Prior-Q with mask upstream
		// log.Println("Mib-upload for prior-q with mask")
		pkt = []byte{
			0x00, 0x42, 0x2e, 0x0a, 0x00, 0x02, 0x00, 0x00,
			0x01, 0x15, 0x80, 0x00, 0x00, 0x0f, 0xff, 0xff,
			0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
			0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		}
		pkt[11] = state.priorQInstance

	case 29,  33,  37, 41, 45, 49, 53, 57,
	     61,  65,  69, 73, 77, 81, 85, 89,
	     93, 97,  101, 105, 109, 113, 117, 121,
	     125, 129, 133, 137, 141, 145, 149, 153,
	     157, 161, 165, 169, 173, 177, 181, 185,
	     189, 193, 197, 201, 205, 209, 213, 217,
	     221, 225, 229, 233, 237, 241, 245, 249,
	     253, 257, 261, 265, 269, 273, 277, 281:
		// Prior-Q with attribute list upstream
		// log.Println("Mib-upload for prior-q with attribute list")
		// For upstream pkt[10] is fixed as 80
		// So for upstream PQ, instanceId will be like 0x8001, 0x8002 ... etc
		pkt = []byte{
			0x00, 0x43, 0x2e, 0x0a, 0x00, 0x02, 0x00, 0x00,
			0x01, 0x15, 0x80, 0x00, 0xff, 0xf0, 0x00, 0x01,
			0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
			0x20, 0x00, 0x00, 0x80, 0x20, 0x01, 0x00, 0x01,
			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		}

		pkt[11] = state.priorQInstance
		pkt[24] = state.tcontPointer
		pkt[26] = state.priorQPriority % NumPriorQPerTcont // Priority of this PriorQ
		pkt[28] = state.tcontInstance
		state.priorQPriority++


	case 282, 283, 284, 285, 286, 287, 288, 289:
		// Traffic Scheduler
		// log.Println("Traffic Scheduler")
		pkt = []byte{
			0x02, 0xa4, 0x2e, 0x0a, 0x00, 0x02, 0x00, 0x00,
			0x01, 0x16, 0x80, 0x00, 0xf0, 0x00, 0x80, 0x00,
			0x00, 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,
		}

		pkt[15] = state.tcontInstance
		state.tcontInstance++

	case 290:
		// ONT-2G
		// log.Println("ONT-2G")
		pkt = []byte{
			0x00, 0x16, 0x2e, 0x0a, 0x00, 0x02, 0x00, 0x00,
			0x01, 0x01, 0x00, 0x00, 0x07, 0xfc, 0x00, 0x40,
			0x08, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
			0x00, 0x7f, 0x00, 0x00, 0x3f, 0x00, 0x01, 0x00,
			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		}

	default:
		state.extraMibUploadCtr++
		errstr := fmt.Sprintf("%v - Invalid MibUpload request: %d, extras: %d", key, state.mibUploadCtr, state)
		return nil, errors.New(errstr)
	}

	state.mibUploadCtr++
	return pkt, nil
}

func set(class OmciClass, content OmciContent, key OnuKey) ([]byte, error) {
	var pkt []byte

	pkt = []byte{
		0x00, 0x00, 0x00, 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,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}

	log.WithFields(log.Fields{
		"IntfId": key.IntfId,
		"OnuId": key.OnuId,
	}).Tracef("Omci Set")

	return pkt, nil
}

func create(class OmciClass, content OmciContent, key OnuKey) ([]byte, error) {
	var pkt []byte

	if class == GEMPortNetworkCTP {
		OnuOmciStateMapLock.RLock()
		defer OnuOmciStateMapLock.RUnlock()
		if onuOmciState, ok := OnuOmciStateMap[key]; !ok {
			log.WithFields(log.Fields{
				"IntfId": key.IntfId,
				"OnuId": key.OnuId,
			}).Tracef("ONU Key Error")
			return nil, errors.New("ONU Key Error")
		} else {
			onuOmciState.gemPortId = binary.BigEndian.Uint16(content[:2])
			log.WithFields(log.Fields{
				"IntfId": key.IntfId,
				"OnuId": key.OnuId,
			}).Tracef("Gem Port Id %d", key, onuOmciState)
			// FIXME
			OnuOmciStateMap[key].state = DONE
			omciCh <- OmciChMessage{
				Type: GemPortAdded,
				Data: OmciChMessageData{
					OnuId: key.OnuId,
					IntfId: key.IntfId,
				},
			}
		}
	}

	pkt = []byte{
		0x00, 0x00, 0x00, 0x00, 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, 0x00, 0x00, 0x00, 0x00, 0x00}

	log.WithFields(log.Fields{
		"IntfId": key.IntfId,
		"OnuId": key.OnuId,
	}).Tracef("Omci Create")

	return pkt, nil
}

func get(class OmciClass, content OmciContent, key OnuKey) ([]byte, error) {
	var pkt []byte

	pkt = []byte{
		0x00, 0x00, 0x00, 0x00, 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, 0x00, 0x00, 0x00, 0x00, 0x00}

	pkt = GetAttributes(class, content, key, pkt)

	log.WithFields(log.Fields{
		"IntfId": key.IntfId,
		"OnuId": key.OnuId,
	}).Tracef("Omci Get")
	return pkt, nil
}

func getAllAlarms(class OmciClass, content OmciContent, key OnuKey) ([]byte, error) {
	var pkt []byte

	// Report number of commands as 1, basically there is always one alarm to get, the ONU/PPTP locked, link down or up
	pkt = []byte{
		0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
		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, 0x00, 0x00, 0x00}

	log.WithFields(log.Fields{
		"IntfId": key.IntfId,
		"OnuId": key.OnuId,
	}).Tracef("Omci GetAllAlarms")

	return pkt, nil
}

func syncTime(class OmciClass, content OmciContent, key OnuKey) ([]byte, error) {
	var pkt []byte

	pkt = []byte{
		0x00, 0x00, 0x00, 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,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}

	log.WithFields(log.Fields{
		"IntfId": key.IntfId,
		"OnuId": key.OnuId,
	}).Tracef("Omci syncTime")

	return pkt, nil
}

func getAllAlarmsNext(class OmciClass, content OmciContent, key OnuKey) ([]byte, error) {
	var pkt []byte

	OnuOmciStateMapLock.Lock()
	if OnuOmciState, ok := OnuOmciStateMap[key]; ok {
		// if we are locked then admin down was sent and PPTP 257 is in alarm/locked state, this ensures get alarm
		// shows that
		if OnuOmciState.state == LOCKED {
			// alarm set, alarm spot 0, LAN LOS
			pkt = []byte{
				0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
				0x00, 0x0b, 0x01, 0x01, 0x80, 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}
		} else {
			// alarm clear
			pkt = []byte{
				0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
				0x00, 0x0b, 0x01, 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}
		}
	}
	OnuOmciStateMapLock.Unlock()

	log.WithFields(log.Fields{
		"IntfId": key.IntfId,
		"OnuId": key.OnuId,
	}).Tracef("Omci GetAllAlarmsNext")

	return pkt, nil
}

func delete(class OmciClass, content OmciContent, key OnuKey) ([]byte, error) {
	var pkt []byte

	pkt = []byte{
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x0b, 0x00, 0x00, 0x80, 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}

	log.WithFields(log.Fields{
		"IntfId": key.IntfId,
		"OnuId": key.OnuId,
	}).Tracef("Omci Delete")

	return pkt, nil
}

func reboot(class OmciClass, content OmciContent, key OnuKey) ([]byte, error) {
	var pkt []byte
	pkt = []byte{
		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, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}

	log.WithFields(log.Fields{
		"IntfId": key.IntfId,
		"OnuId": key.OnuId,
	}).Tracef("Omci Reboot")
	return pkt, nil
}

func testHandler(class OmciClass, content OmciContent, key OnuKey) ([]byte, error) {
	var pkt []byte
	pkt = []byte{
		0x20, 0x52, 0x45, 0x43, 0x56, 0x00, 0x20, 0x53,
		0x45, 0x4e, 0x44, 0x00, 0x88, 0xb5, 0x02, 0x3f,
		0x1b, 0x0a, 0x01, 0x07, 0x80, 0x01, 0x01, 0x00,
		0xa5, 0x03, 0xe0, 0x0b, 0x05, 0x0b, 0x2b, 0x09,
		0x1c, 0xd0, 0x0c, 0x32, 0x80, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x28, 0xf8, 0x13, 0x1b, 0x36,}

	log.WithFields(log.Fields{
		"IntfId": key.IntfId,
		"OnuId": key.OnuId,
	}).Trace("Omci Test")
	return pkt, nil
}

