/*
 Copyright 2017 the original author or authors.

 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 inventory

import (
	"encoding/json"
	"net"

	"gerrit.opencord.org/abstract-olt/models"
	"gerrit.opencord.org/abstract-olt/models/physical"
)

type Chassis struct {
	Clli      string
	Rack      int
	Shelf     int
	XOSAddr   net.TCPAddr
	LineCards []LineCard
}
type LineCard struct {
	Number int
	Olts   []PhysicalOlt
}
type PhysicalOlt struct {
	Address  net.TCPAddr
	Hostname string
	Ports    []Port
}
type Port struct {
	AbstractNumber int
	PhysicalNumber int
	Onts           []Ont
}
type Ont struct {
	Number       int
	SVlan        uint32
	CVlan        uint32
	SerialNumber string
	NasPortID    string
	CircuitID    string
}

func GatherAllInventory() string {
	chassisMap := models.GetChassisMap()
	chassis_s := []Chassis{}
	for clli, chassisHolder := range *chassisMap {
		chassis := parseClli(clli, chassisHolder)
		chassis_s = append(chassis_s, chassis)
	}
	bytes, _ := json.Marshal(chassis_s)
	return string(bytes)
}

func GatherInventory(clli string) string {
	chassisMap := models.GetChassisMap()
	chassisHolder := (*chassisMap)[clli]
	chassis := parseClli(clli, chassisHolder)
	bytes, _ := json.Marshal(chassis)
	return string(bytes)
}

func parseClli(clli string, chassisHolder *models.ChassisHolder) Chassis {
	abstract := chassisHolder.AbstractChassis
	chassis := Chassis{}
	chassis.Clli = clli
	chassis.Rack = abstract.Rack
	chassis.Shelf = abstract.Shelf
	chassis.XOSAddr = chassisHolder.PhysicalChassis.XOSAddress

	lineCards := []LineCard{}
	for index, slot := range abstract.Slots {
		if slot.Ports[0].PhysPort != nil {
			lineCard := LineCard{Number: index + 1}
			var currentOLT *physical.SimpleOLT
			var physicalOLT PhysicalOlt
			var ports []Port
			olts := []PhysicalOlt{}
			for i := 0; i < 16; i++ {
				ponPort := slot.Ports[i].PhysPort
				if ponPort != nil {
					parentOLT := ponPort.Parent
					if currentOLT != parentOLT {
						if currentOLT != nil {
							physicalOLT.Ports = ports
							olts = append(olts, physicalOLT)
						}
						physicalOLT = PhysicalOlt{Address: parentOLT.Address, Hostname: parentOLT.Hostname}
						currentOLT = parentOLT
						ports = []Port{}

					}
					port := Port{AbstractNumber: i + 1, PhysicalNumber: ponPort.Number}
					onts := []Ont{}
					for _, physicalONT := range ponPort.Onts {
						if physicalONT.Active {
							ont := Ont{Number: physicalONT.Number, SVlan: physicalONT.Svlan, CVlan: physicalONT.Cvlan, SerialNumber: physicalONT.SerialNumber,
								NasPortID: physicalONT.NasPortID, CircuitID: physicalONT.CircuitID}
							onts = append(onts, ont)
						}
					}
					port.Onts = onts
					ports = append(ports, port)
				}

				if i == 15 { // last one
					physicalOLT.Ports = ports
					olts = append(olts, physicalOLT)
				}
			}
			lineCard.Olts = olts
			lineCards = append(lineCards, lineCard)
		}
	}
	chassis.LineCards = lineCards
	return chassis
}
