/*
 * 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 (
	"context"
	"gerrit.opencord.org/voltha-bbsim/common/logger"
	openolt "gerrit.opencord.org/voltha-bbsim/protos"
	omci "github.com/opencord/omci-sim"
)

// RunOmciResponder starts a go routine to process/respond to OMCI messages from VOLTHA
func (s *Server) RunOmciResponder(ctx context.Context, omciOut chan openolt.OmciMsg, omciIn chan openolt.OmciIndication, errch chan error) {
	go func() {
		defer logger.Debug("Omci response process was done")

		var resp openolt.OmciIndication

		for {
			select {
			case m := <-omciOut:
				respPkt, err := omci.OmciSim(m.IntfId, m.OnuId, HexDecode(m.Pkt))
				switch err := err.(type) {
				case nil:
					// Success
					resp.IntfId = m.IntfId
					resp.OnuId = m.OnuId
					resp.Pkt = respPkt
					omciIn <- resp
					s.handleOmciAction(resp.Pkt, resp.IntfId, resp.OnuId)


				case *omci.OmciError:
					// Error in processing omci message. Log and carry on.
					logger.Debug("%s", err.Msg)
					continue
				default:
					// Fatal error, exit.
					errch <- err
					return
				}
			case <-ctx.Done():
				return
			}
		}
	}()
}

// HexDecode converts the hex encoding to binary
func HexDecode(pkt []byte) []byte {
	// TODO - Change openolt adapter to send raw binary instead of hex encoded
	p := make([]byte, len(pkt)/2)
	for i, j := 0, 0; i < len(pkt); i, j = i+2, j+1 {
		// Go figure this ;)
		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)
	return p
}

func (s *Server) handleOmciAction(pkt []byte, IntfID uint32, OnuID uint32) {
	logger.Debug("handleOmciAction invoked")
	MEClass := omci.OmciClass(uint16(pkt[5]) | uint16(pkt[4])<<8)
	msgType := omci.OmciMsgType(pkt[2] & 0x1F)
	logger.Debug("ME Class %d, msgType %d", MEClass, msgType)

	if MEClass == omci.ONUG {
		switch msgType {
		case omci.Reboot:
			logger.Info("ONU reboot recieved")
			s.handleONUSoftReboot(IntfID, OnuID)
		}
	}
}
