/*
 * Copyright (c) 2018 - present.  Boling Consulting Solutions (bcsw.net)
 * Copyright 2020-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 omci

import (
	"encoding/binary"
	"errors"
	"fmt"

	"github.com/google/gopacket"
	me "github.com/opencord/omci-lib-go/v2/generated"
)

type GetAllAlarmsRequest struct {
	MeBasePacket
	AlarmRetrievalMode byte
}

func (omci *GetAllAlarmsRequest) String() string {
	return fmt.Sprintf("%v, Retrieval Mode: %v",
		omci.MeBasePacket.String(), omci.AlarmRetrievalMode)
}

// LayerType returns LayerTypeGetAllAlarmsRequest
func (omci *GetAllAlarmsRequest) LayerType() gopacket.LayerType {
	return LayerTypeGetAllAlarmsRequest
}

// CanDecode returns the set of layer types that this DecodingLayer can decode
func (omci *GetAllAlarmsRequest) CanDecode() gopacket.LayerClass {
	return LayerTypeGetAllAlarmsRequest
}

// NextLayerType returns the layer type contained by this DecodingLayer.
func (omci *GetAllAlarmsRequest) NextLayerType() gopacket.LayerType {
	return gopacket.LayerTypePayload
}

// DecodeFromBytes decodes the given bytes of a Get All Alarms Request into this layer
func (omci *GetAllAlarmsRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
	// Common ClassID/EntityID decode in msgBase
	var hdrSize int
	if omci.Extended {
		//start here
		hdrSize = 6 + 1
	} else {
		hdrSize = 4 + 1
	}
	err := omci.MeBasePacket.DecodeFromBytes(data, p, hdrSize)
	if err != nil {
		return err
	}
	meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
		me.ParamData{EntityID: omci.EntityInstance})
	if omciErr.StatusCode() != me.Success {
		return omciErr.GetError()
	}
	// ME needs to support Get All Alarms
	if !me.SupportsMsgType(meDefinition, me.GetAllAlarms) {
		return me.NewProcessingError("managed entity does not support Get All Alarms Message-Type")
	}
	// Entity Class are always ONU DATA (2) and Entity Instance of 0
	if omci.EntityClass != me.OnuDataClassID {
		msg := fmt.Sprintf("invalid Entity Class for Get All Alarms request: %v",
			omci.EntityClass)
		return me.NewProcessingError(msg)
	}
	if omci.EntityInstance != 0 {
		msg := fmt.Sprintf("invalid Entity Instance for Get All Alarms request: %v",
			omci.EntityInstance)
		return me.NewUnknownInstanceError(msg)
	}
	var offset int
	if omci.Extended {
		offset = 2
	}
	omci.AlarmRetrievalMode = data[4+offset]
	if omci.AlarmRetrievalMode > 1 {
		msg := fmt.Sprintf("invalid Alarm Retrieval Mode for Get All Alarms request: %v, must be 0..1",
			omci.AlarmRetrievalMode)
		return errors.New(msg)
	}
	return nil
}

func decodeGetAllAlarmsRequest(data []byte, p gopacket.PacketBuilder) error {
	omci := &GetAllAlarmsRequest{}
	omci.MsgLayerType = LayerTypeGetAllAlarmsRequest
	return decodingLayerDecoder(omci, data, p)
}

func decodeGetAllAlarmsRequestExtended(data []byte, p gopacket.PacketBuilder) error {
	omci := &GetAllAlarmsRequest{}
	omci.MsgLayerType = LayerTypeGetAllAlarmsRequest
	omci.Extended = true
	return decodingLayerDecoder(omci, data, p)
}

// SerializeTo provides serialization of an Get All Alarms Request message
func (omci *GetAllAlarmsRequest) SerializeTo(b gopacket.SerializeBuffer, _ gopacket.SerializeOptions) error {
	// Basic (common) OMCI Header is 8 octets, 10
	err := omci.MeBasePacket.SerializeTo(b)
	if err != nil {
		return err
	}
	entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
		me.ParamData{EntityID: omci.EntityInstance})
	if omciErr.StatusCode() != me.Success {
		return omciErr.GetError()
	}
	// ME needs to support Get All Alarms
	if !me.SupportsMsgType(entity, me.GetAllAlarms) {
		return me.NewProcessingError("managed entity does not support the Get All Alarms Message-Type")
	}
	var offset int
	if omci.Extended {
		offset = 2
	}
	bytes, err := b.AppendBytes(offset + 1)
	if err != nil {
		return err
	}
	if omci.Extended {
		binary.BigEndian.PutUint16(bytes, uint16(1))
	}
	bytes[offset] = omci.AlarmRetrievalMode
	return nil
}

type GetAllAlarmsResponse struct {
	MeBasePacket
	NumberOfCommands uint16
}

func (omci *GetAllAlarmsResponse) String() string {
	return fmt.Sprintf("%v, NumberOfCommands: %d",
		omci.MeBasePacket.String(), omci.NumberOfCommands)
}

// LayerType returns LayerTypeGetAllAlarmsResponse
func (omci *GetAllAlarmsResponse) LayerType() gopacket.LayerType {
	return LayerTypeGetAllAlarmsResponse
}

// CanDecode returns the set of layer types that this DecodingLayer can decode
func (omci *GetAllAlarmsResponse) CanDecode() gopacket.LayerClass {
	return LayerTypeGetAllAlarmsResponse
}

// NextLayerType returns the layer type contained by this DecodingLayer.
func (omci *GetAllAlarmsResponse) NextLayerType() gopacket.LayerType {
	return gopacket.LayerTypePayload
}

// DecodeFromBytes decodes the given bytes of a Get All Alarms Response into this layer
func (omci *GetAllAlarmsResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
	// Common ClassID/EntityID decode in msgBase
	var hdrSize int
	if omci.Extended {
		//start here
		hdrSize = 6 + 2
	} else {
		hdrSize = 4 + 2
	}
	err := omci.MeBasePacket.DecodeFromBytes(data, p, hdrSize)
	if err != nil {
		return err
	}
	meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
		me.ParamData{EntityID: omci.EntityInstance})
	if omciErr.StatusCode() != me.Success {
		return omciErr.GetError()
	}
	// ME needs to support Get All Alarms
	if !me.SupportsMsgType(meDefinition, me.GetAllAlarms) {
		return me.NewProcessingError("managed entity does not support Get All Alarms Message-Type")
	}
	// Entity Class are always ONU DATA (2) and Entity Instance of 0
	if omci.EntityClass != me.OnuDataClassID {
		msg := fmt.Sprintf("invalid Entity Class for Get All Alarms response: %v",
			omci.EntityClass)
		return me.NewProcessingError(msg)
	}
	if omci.EntityInstance != 0 {
		msg := fmt.Sprintf("invalid Entity Instance for Get All Alarms response: %v",
			omci.EntityInstance)
		return me.NewUnknownInstanceError(msg)
	}
	var offset int
	if omci.Extended {
		offset = 2
	}
	omci.NumberOfCommands = binary.BigEndian.Uint16(data[4+offset:])
	return nil
}

func decodeGetAllAlarmsResponse(data []byte, p gopacket.PacketBuilder) error {
	omci := &GetAllAlarmsResponse{}
	omci.MsgLayerType = LayerTypeGetAllAlarmsResponse
	return decodingLayerDecoder(omci, data, p)
}

func decodeGetAllAlarmsResponseExtended(data []byte, p gopacket.PacketBuilder) error {
	omci := &GetAllAlarmsResponse{}
	omci.MsgLayerType = LayerTypeGetAllAlarmsResponse
	omci.Extended = true
	return decodingLayerDecoder(omci, data, p)
}

// SerializeTo provides serialization of an Get All Alarms Response message
func (omci *GetAllAlarmsResponse) SerializeTo(b gopacket.SerializeBuffer, _ gopacket.SerializeOptions) error {
	// Basic (common) OMCI Header is 8 octets, 10
	err := omci.MeBasePacket.SerializeTo(b)
	if err != nil {
		return err
	}
	entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
		me.ParamData{EntityID: omci.EntityInstance})
	if omciErr.StatusCode() != me.Success {
		return omciErr.GetError()
	}
	// ME needs to support Get All Alarms
	if !me.SupportsMsgType(entity, me.GetAllAlarms) {
		return me.NewProcessingError("managed entity does not support the Get All Alarms Message-Type")
	}
	var offset int
	if omci.Extended {
		offset = 2
	}
	bytes, err := b.AppendBytes(offset + 2)
	if err != nil {
		return err
	}
	if omci.Extended {
		binary.BigEndian.PutUint16(bytes, uint16(2))
	}
	binary.BigEndian.PutUint16(bytes[offset:], omci.NumberOfCommands)
	return nil
}

type GetAllAlarmsNextRequest struct {
	MeBasePacket
	CommandSequenceNumber uint16
}

func (omci *GetAllAlarmsNextRequest) String() string {
	return fmt.Sprintf("%v, Sequence Number: %d",
		omci.MeBasePacket.String(), omci.CommandSequenceNumber)
}

// LayerType returns LayerTypeGetAllAlarmsNextRequest
func (omci *GetAllAlarmsNextRequest) LayerType() gopacket.LayerType {
	return LayerTypeGetAllAlarmsNextRequest
}

// CanDecode returns the set of layer types that this DecodingLayer can decode
func (omci *GetAllAlarmsNextRequest) CanDecode() gopacket.LayerClass {
	return LayerTypeGetAllAlarmsNextRequest
}

// NextLayerType returns the layer type contained by this DecodingLayer.
func (omci *GetAllAlarmsNextRequest) NextLayerType() gopacket.LayerType {
	return gopacket.LayerTypePayload
}

// DecodeFromBytes decodes the given bytes of a Get All Alarms Next Request into this layer
func (omci *GetAllAlarmsNextRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
	// Common ClassID/EntityID decode in msgBase
	var hdrSize int
	if omci.Extended {
		//start here
		hdrSize = 6 + 2
	} else {
		hdrSize = 4 + 2
	}
	err := omci.MeBasePacket.DecodeFromBytes(data, p, hdrSize)
	if err != nil {
		return err
	}
	meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
		me.ParamData{EntityID: omci.EntityInstance})
	if omciErr.StatusCode() != me.Success {
		return omciErr.GetError()
	}
	// ME needs to support Get All Alarms
	if !me.SupportsMsgType(meDefinition, me.GetAllAlarmsNext) {
		return me.NewProcessingError("managed entity does not support Get All Alarms Next Message-Type")
	}
	// Entity Class are always ONU DATA (2) and Entity Instance of 0
	if omci.EntityClass != me.OnuDataClassID {
		msg := fmt.Sprintf("invalid Entity Class for Get All Alarms Next request: %v",
			omci.EntityClass)
		return me.NewProcessingError(msg)
	}
	if omci.EntityInstance != 0 {
		msg := fmt.Sprintf("invalid Entity Instance for Get All Alarms Next request: %v",
			omci.EntityInstance)
		return me.NewUnknownInstanceError(msg)
	}
	var offset int
	if omci.Extended {
		offset = 2
	}
	omci.CommandSequenceNumber = binary.BigEndian.Uint16(data[4+offset:])
	return nil
}

func decodeGetAllAlarmsNextRequest(data []byte, p gopacket.PacketBuilder) error {
	omci := &GetAllAlarmsNextRequest{}
	omci.MsgLayerType = LayerTypeGetAllAlarmsNextRequest
	return decodingLayerDecoder(omci, data, p)
}

func decodeGetAllAlarmsNextRequestExtended(data []byte, p gopacket.PacketBuilder) error {
	omci := &GetAllAlarmsNextRequest{}
	omci.MsgLayerType = LayerTypeGetAllAlarmsNextRequest
	omci.Extended = true
	return decodingLayerDecoder(omci, data, p)
}

// SerializeTo provides serialization of an Get All Alarms Next Request message
func (omci *GetAllAlarmsNextRequest) SerializeTo(b gopacket.SerializeBuffer, _ gopacket.SerializeOptions) error {
	// Basic (common) OMCI Header is 8 octets, 10
	err := omci.MeBasePacket.SerializeTo(b)
	if err != nil {
		return err
	}
	entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
		me.ParamData{EntityID: omci.EntityInstance})
	if omciErr.StatusCode() != me.Success {
		return omciErr.GetError()
	}
	// ME needs to support Get All Alarms Next
	if !me.SupportsMsgType(entity, me.GetAllAlarmsNext) {
		return me.NewProcessingError("managed entity does not support the Get All Alarms Next Message-Type")
	}
	var offset int
	if omci.Extended {
		offset = 2
	}
	bytes, err := b.AppendBytes(offset + 2)
	if err != nil {
		return err
	}
	if omci.Extended {
		binary.BigEndian.PutUint16(bytes, uint16(2))
	}
	binary.BigEndian.PutUint16(bytes[offset:], omci.CommandSequenceNumber)
	return nil
}

type AdditionalAlarmsData struct {
	AlarmEntityClass    me.ClassID
	AlarmEntityInstance uint16
	AlarmBitMap         [28]byte // 224 bits
}

type GetAllAlarmsNextResponse struct {
	MeBasePacket
	AlarmEntityClass    me.ClassID
	AlarmEntityInstance uint16
	AlarmBitMap         [28]byte               // 224 bits
	AdditionalAlarms    []AdditionalAlarmsData // Valid only for extended message set version
}

func (omci *GetAllAlarmsNextResponse) String() string {
	return fmt.Sprintf("%v, CID: %v, EID: (%d/%#x), Bitmap: %v",
		omci.MeBasePacket.String(), omci.AlarmEntityClass, omci.AlarmEntityInstance,
		omci.AlarmEntityInstance, omci.AlarmBitMap)
}

// LayerType returns LayerTypeGetAllAlarmsNextResponse
func (omci *GetAllAlarmsNextResponse) LayerType() gopacket.LayerType {
	return LayerTypeGetAllAlarmsNextResponse
}

// CanDecode returns the set of layer types that this DecodingLayer can decode
func (omci *GetAllAlarmsNextResponse) CanDecode() gopacket.LayerClass {
	return LayerTypeGetAllAlarmsNextResponse
}

// NextLayerType returns the layer type contained by this DecodingLayer.
func (omci *GetAllAlarmsNextResponse) NextLayerType() gopacket.LayerType {
	return gopacket.LayerTypePayload
}

// DecodeFromBytes decodes the given bytes of a Get All Alarms Next Response into this layer
func (omci *GetAllAlarmsNextResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
	// Common ClassID/EntityID decode in msgBase
	var hdrSize int
	if omci.Extended {
		hdrSize = 6
	} else {
		hdrSize = 4
	}
	err := omci.MeBasePacket.DecodeFromBytes(data, p, hdrSize)
	if err != nil {
		return err
	}
	meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
		me.ParamData{EntityID: omci.EntityInstance})
	if omciErr.StatusCode() != me.Success {
		return omciErr.GetError()
	}
	// ME needs to support Get All Alarms Next
	if !me.SupportsMsgType(meDefinition, me.GetAllAlarmsNext) {
		return me.NewProcessingError("managed entity does not support Get All Alarms Next Message-Type")
	}
	// Entity Class are always ONU DATA (2) and Entity Instance of 0
	if omci.EntityClass != me.OnuDataClassID {
		msg := fmt.Sprintf("invalid Entity Class for Get All Alarms Next response: %v",
			omci.EntityClass)
		return me.NewProcessingError(msg)
	}
	if omci.EntityInstance != 0 {
		msg := fmt.Sprintf("invalid Entity Instance for Get All Alarms Next response: %v",
			omci.EntityInstance)
		return me.NewUnknownInstanceError(msg)
	}
	//err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+4+28)	// Decode reported ME.  If an out-of-range sequence number was sent, this will
	//	// contain an ME with class ID and entity ID of zero and you should get an
	//	// error of "managed entity definition not found" returned.
	var offset int
	msgContentsLen := 28
	if omci.Extended {
		offset = 2 // Message Contents length (2)
		msgContentsLen = int(binary.BigEndian.Uint16(data[6:]))
	}
	if len(data[4+offset:]) < 4+msgContentsLen {
		p.SetTruncated()
		return errors.New("frame too small: Get All Alarms Next Response Managed Entity attribute truncated")
	}
	omci.AlarmEntityClass = me.ClassID(binary.BigEndian.Uint16(data[4+offset:]))
	omci.AlarmEntityInstance = binary.BigEndian.Uint16(data[6+offset:])

	copy(omci.AlarmBitMap[:], data[8+offset:36])
	remaining := len(data) - (6 + 4 + 28)

	if !omci.Extended || remaining <= 0 {
		return nil
	}
	offset = 6 + 4 + 28
	omci.AdditionalAlarms = make([]AdditionalAlarmsData, 0)
	for remaining > 0 {
		if remaining < 4+28 {
			p.SetTruncated()
			return errors.New("frame too small: Get All Alarms Next Response Managed Entity attribute truncated")
		}
		alarm := AdditionalAlarmsData{
			AlarmEntityClass:    me.ClassID(binary.BigEndian.Uint16(data[offset:])),
			AlarmEntityInstance: binary.BigEndian.Uint16(data[offset+2:]),
		}
		copy(alarm.AlarmBitMap[:], data[offset+4:])
		omci.AdditionalAlarms = append(omci.AdditionalAlarms, alarm)

		offset += 4 + 28
		remaining -= 4 + 28
	}
	return nil
}

func decodeGetAllAlarmsNextResponse(data []byte, p gopacket.PacketBuilder) error {
	omci := &GetAllAlarmsNextResponse{}
	omci.MsgLayerType = LayerTypeGetAllAlarmsNextResponse
	return decodingLayerDecoder(omci, data, p)
}

func decodeGetAllAlarmsNextResponseExtended(data []byte, p gopacket.PacketBuilder) error {
	omci := &GetAllAlarmsNextResponse{}
	omci.MsgLayerType = LayerTypeGetAllAlarmsNextResponse
	omci.Extended = true
	return decodingLayerDecoder(omci, data, p)
}

// SerializeTo provides serialization of an Get All Alarms Next Response message
func (omci *GetAllAlarmsNextResponse) SerializeTo(b gopacket.SerializeBuffer, _ gopacket.SerializeOptions) error {
	// Basic (common) OMCI Header is 8 octets, 10
	err := omci.MeBasePacket.SerializeTo(b)
	if err != nil {
		return err
	}
	entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
		me.ParamData{EntityID: omci.EntityInstance})
	if omciErr.StatusCode() != me.Success {
		return omciErr.GetError()
	}
	// ME needs to support Get All Alarms Next
	if !me.SupportsMsgType(entity, me.GetAllAlarmsNext) {
		return me.NewProcessingError("managed entity does not support the Get All Alarms Next Message-Type")
	}
	contentLength := 2 + 2 + 28
	maxLength := MaxBaselineLength - 8 - 8
	var extraMEs int
	var offset int

	if omci.Extended {
		maxLength = MaxExtendedLength - 10 - 4
		offset = 2
		contentLength += 2 // Length field
		if omci.AdditionalAlarms != nil {
			extraMEs = len(omci.AdditionalAlarms)
			contentLength += extraMEs * (4 + 28)
		}
	}
	if contentLength > maxLength {
		msg := fmt.Sprintf("not enough space to fit all requested Managed Entities, have %v, requested: %v",
			maxLength, contentLength)
		return me.NewMessageTruncatedError(msg)
	}
	// Allocate space for all
	bytes, err := b.AppendBytes(contentLength)
	if err != nil {
		return err
	}
	// Always encode the first ME alarm data
	binary.BigEndian.PutUint16(bytes[offset:], uint16(omci.AlarmEntityClass))
	binary.BigEndian.PutUint16(bytes[offset+2:], omci.AlarmEntityInstance)
	copy(bytes[offset+4:], omci.AlarmBitMap[:])

	if omci.Extended {
		binary.BigEndian.PutUint16(bytes, uint16(contentLength-2))

		if omci.AdditionalAlarms != nil {
			for index, value := range omci.AdditionalAlarms {
				offset = (32 * (index + 1)) + 2
				binary.BigEndian.PutUint16(bytes[offset:], uint16(value.AlarmEntityClass))
				binary.BigEndian.PutUint16(bytes[offset+2:], value.AlarmEntityInstance)
				copy(bytes[offset+4:], value.AlarmBitMap[:])
			}
		}
	}
	return nil
}

const AlarmBitmapSize = 224

type AlarmNotificationMsg struct {
	MeBasePacket
	AlarmBitmap         [AlarmBitmapSize / 8]byte
	zeroPadding         [3]byte // Note: This zero padding is not present in the Extended Message Set
	AlarmSequenceNumber byte
}

func (omci *AlarmNotificationMsg) String() string {
	return fmt.Sprintf("%v, Sequence Number: %d, Alarm Bitmap: %v",
		omci.MeBasePacket.String(), omci.AlarmSequenceNumber, omci.AlarmBitmap)
}

// LayerType returns LayerTypeAlarmNotification
func (omci *AlarmNotificationMsg) LayerType() gopacket.LayerType {
	return LayerTypeAlarmNotification
}

// CanDecode returns the set of layer types that this DecodingLayer can decode
func (omci *AlarmNotificationMsg) CanDecode() gopacket.LayerClass {
	return LayerTypeAlarmNotification
}

// NextLayerType returns the layer type contained by this DecodingLayer.
func (omci *AlarmNotificationMsg) NextLayerType() gopacket.LayerType {
	return gopacket.LayerTypePayload
}

func (omci *AlarmNotificationMsg) IsAlarmActive(alarmNumber uint8) (bool, error) {
	if alarmNumber >= AlarmBitmapSize {
		msg := fmt.Sprintf("invalid alarm number: %v, must be 0..224", alarmNumber)
		return false, errors.New(msg)
	}
	entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
		me.ParamData{EntityID: omci.EntityInstance})
	if omciErr.StatusCode() != me.Success {
		return false, omciErr.GetError()
	}
	alarmMap := entity.GetAlarmMap()
	if alarmMap == nil {
		msg := "managed entity does not support Alarm notifications"
		return false, errors.New(msg)
	}
	if _, ok := alarmMap[alarmNumber]; !ok {
		msg := fmt.Sprintf("unsupported invalid alarm number: %v", alarmNumber)
		return false, errors.New(msg)
	}
	octet := alarmNumber / 8
	bit := 7 - (alarmNumber % 8)
	return omci.AlarmBitmap[octet]>>bit == 1, nil
}

func (omci *AlarmNotificationMsg) IsAlarmClear(alarmNumber uint8) (bool, error) {
	if alarmNumber >= AlarmBitmapSize {
		msg := fmt.Sprintf("invalid alarm number: %v, must be 0..224", alarmNumber)
		return false, errors.New(msg)
	}
	entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
		me.ParamData{EntityID: omci.EntityInstance})
	if omciErr.StatusCode() != me.Success {
		return false, omciErr.GetError()
	}
	alarmMap := entity.GetAlarmMap()
	if alarmMap == nil {
		return false, errors.New("managed entity does not support Alarm notifications")
	}
	if _, ok := alarmMap[alarmNumber]; !ok {
		msg := fmt.Sprintf("unsupported invalid alarm number: %v", alarmNumber)
		return false, errors.New(msg)
	}
	octet := alarmNumber / 8
	bit := 7 - (alarmNumber % 8)
	return omci.AlarmBitmap[octet]>>bit == 0, nil
}

func (omci *AlarmNotificationMsg) ActivateAlarm(alarmNumber uint8) error {
	if alarmNumber >= AlarmBitmapSize {
		msg := fmt.Sprintf("invalid alarm number: %v, must be 0..224", alarmNumber)
		return errors.New(msg)
	}
	entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
		me.ParamData{EntityID: omci.EntityInstance})
	if omciErr.StatusCode() != me.Success {
		return omciErr.GetError()
	}
	alarmMap := entity.GetAlarmMap()
	if alarmMap == nil {
		return errors.New("managed entity does not support Alarm notifications")
	}
	if _, ok := alarmMap[alarmNumber]; !ok {
		msg := fmt.Sprintf("unsupported invalid alarm number: %v", alarmNumber)
		return errors.New(msg)
	}
	octet := alarmNumber / 8
	bit := 7 - (alarmNumber % 8)
	omci.AlarmBitmap[octet] |= 1 << bit
	return nil
}

func (omci *AlarmNotificationMsg) ClearAlarm(alarmNumber uint8) error {
	if alarmNumber >= AlarmBitmapSize {
		msg := fmt.Sprintf("invalid alarm number: %v, must be 0..224", alarmNumber)
		return errors.New(msg)
	}
	entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
		me.ParamData{EntityID: omci.EntityInstance})
	if omciErr.StatusCode() != me.Success {
		return omciErr.GetError()
	}
	alarmMap := entity.GetAlarmMap()
	if alarmMap == nil {
		return errors.New("managed entity does not support Alarm notifications")
	}
	if _, ok := alarmMap[alarmNumber]; !ok {
		msg := fmt.Sprintf("unsupported invalid alarm number: %v", alarmNumber)
		return errors.New(msg)
	}
	octet := alarmNumber / 8
	bit := 7 - (alarmNumber % 8)
	omci.AlarmBitmap[octet] &= ^(1 << bit)
	return nil
}

// DecodeFromBytes decodes the given bytes of an Alarm Notification into this layer
func (omci *AlarmNotificationMsg) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
	// Common ClassID/EntityID decode in msgBase
	err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+28)
	if err != nil {
		return err
	}
	meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
		me.ParamData{EntityID: omci.EntityInstance})
	if omciErr.StatusCode() != me.Success {
		return omciErr.GetError()
	}
	// Is this an unsupported or vendor specific ME.  If so, it is not an error to decode
	// the alarms.  We just cannot provide any alarm names.  Handle decode here.
	classSupport := meDefinition.GetClassSupport()
	isUnsupported := classSupport == me.UnsupportedManagedEntity ||
		classSupport == me.UnsupportedVendorSpecificManagedEntity

	mapOffset := 4
	if omci.Extended {
		mapOffset = 6
		if len(data) < 6+28+1 {
			p.SetTruncated()
			return errors.New("frame too small")
		}
	}
	// Look for a non-nil/not empty Alarm Map to determine if this ME supports alarms
	if alarmMap := meDefinition.GetAlarmMap(); isUnsupported || (alarmMap != nil && len(alarmMap) > 0) {
		for index, octet := range data[mapOffset : (AlarmBitmapSize/8)-mapOffset] {
			omci.AlarmBitmap[index] = octet
		}
		if omci.Extended {
			omci.AlarmSequenceNumber = data[mapOffset+(AlarmBitmapSize/8)]
		} else {
			padOffset := mapOffset + (AlarmBitmapSize / 8)
			omci.zeroPadding[0] = data[padOffset]
			omci.zeroPadding[1] = data[padOffset+1]
			omci.zeroPadding[2] = data[padOffset+2]
			omci.AlarmSequenceNumber = data[padOffset+3]
		}
		return nil
	}
	return me.NewProcessingError("managed entity does not support alarm notifications")
}

func decodeAlarmNotification(data []byte, p gopacket.PacketBuilder) error {
	omci := &AlarmNotificationMsg{}
	omci.MsgLayerType = LayerTypeAlarmNotification
	return decodingLayerDecoder(omci, data, p)
}

func decodeAlarmNotificationExtended(data []byte, p gopacket.PacketBuilder) error {
	omci := &AlarmNotificationMsg{}
	omci.MsgLayerType = LayerTypeAlarmNotification
	omci.Extended = true
	return decodingLayerDecoder(omci, data, p)
}

// SerializeTo provides serialization of an Alarm Notification message
func (omci *AlarmNotificationMsg) SerializeTo(b gopacket.SerializeBuffer, _ gopacket.SerializeOptions) error {
	// Basic (common) OMCI Header is 8 octets, 10
	err := omci.MeBasePacket.SerializeTo(b)
	if err != nil {
		return err
	}
	// TODO: Support of encoding AlarmNotification into supported types not yet supported
	//meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
	//	me.ParamData{EntityID: omci.EntityInstance})
	//if omciErr.StatusCode() != me.Success {
	//	return omciErr.GetError()
	//}
	//if !me.SupportsMsgType(meDefinition, me.AlarmNotification) {
	//	return me.NewProcessingError("managed entity does not support Alarm Notification Message-Type")
	//}
	if omci.Extended {
		bytes, err := b.AppendBytes(2 + (AlarmBitmapSize / 8) + 1)
		if err != nil {
			return err
		}
		binary.BigEndian.PutUint16(bytes, uint16((AlarmBitmapSize/8)+1))

		for index, octet := range omci.AlarmBitmap {
			bytes[2+index] = octet
		}
		bytes[2+(AlarmBitmapSize/8)] = omci.AlarmSequenceNumber
	} else {
		bytes, err := b.AppendBytes((AlarmBitmapSize / 8) + 3 + 1)
		if err != nil {
			return err
		}
		for index, octet := range omci.AlarmBitmap {
			bytes[index] = octet
		}
		padOffset := AlarmBitmapSize / 8
		bytes[padOffset] = 0
		bytes[padOffset+1] = 0
		bytes[padOffset+2] = 0
		bytes[padOffset+3] = omci.AlarmSequenceNumber
	}
	return nil
}
