package main

import (
	"context"

	"github.com/golang/glog"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"

	pb "code.hackerspace.pl/hscloud/dc/arista-proxy/proto"
)

func (s *server) ShowVersion(ctx context.Context, req *pb.ShowVersionRequest) (*pb.ShowVersionResponse, error) {
	var version []struct {
		ModelName        string  `json:"modelName"`
		InternalVersion  string  `json:"internalVersion"`
		SystemMacAddress string  `json:"systemMacAddress"`
		SerialNumber     string  `json:"serialNumber"`
		MemTotal         int64   `json:"memTotal"`
		BootupTimestamp  float64 `json:"bootupTimestamp"`
		MemFree          int64   `json:"memFree"`
		Version          string  `json:"version"`
		Architecture     string  `json:"architecture"`
		InternalBuildId  string  `json:"internalBuildId"`
		HardwareRevision string  `json:"hardwareRevision"`
	}

	err := s.arista.structuredCall(&version, "show version")
	if err != nil {
		glog.Errorf("EOS Capi: show version: %v", err)
		return nil, status.Error(codes.Unavailable, "EOS Capi call failed")
	}

	if len(version) != 1 {
		glog.Errorf("Expected 1-length result, got %d", len(version))
		return nil, status.Error(codes.Internal, "Internal error")
	}

	d := version[0]

	return &pb.ShowVersionResponse{
		ModelName:        d.ModelName,
		InternalVersion:  d.InternalVersion,
		SystemMacAddress: d.SystemMacAddress,
		SerialNumber:     d.SerialNumber,
		MemTotal:         d.MemTotal,
		BootupTimestamp:  d.BootupTimestamp,
		MemFree:          d.MemFree,
		Version:          d.Version,
		Architecture:     d.Architecture,
		InternalBuildId:  d.InternalBuildId,
		HardwareRevision: d.HardwareRevision,
	}, nil
}

type temperatureSensor struct {
	InAlertState       bool    `json:"inAlertState"`
	MaxTemperature     float64 `json:"maxTemperature"`
	RelPos             string  `json:"relPos"`
	Description        string  `json:"description"`
	Name               string  `json:"name"`
	AlertCount         int64   `json:"alertCount"`
	CurrentTemperature float64 `json:"currentTemperature"`
	OverheatThreshold  float64 `json:"overheatThreshold"`
	CriticalThreshold  float64 `json:"criticalThreshold"`
	HwStatus           string  `json:"hwStatus"`
}

func (t *temperatureSensor) Proto() *pb.ShowEnvironmentTemperatureResponse_TemperatureSensor {
	return &pb.ShowEnvironmentTemperatureResponse_TemperatureSensor{
		InAlertState:       t.InAlertState,
		MaxTemperature:     t.MaxTemperature,
		RelPos:             t.RelPos,
		Description:        t.Description,
		Name:               t.Name,
		AlertCount:         t.AlertCount,
		CurrentTemperature: t.CurrentTemperature,
		OverheatThreshold:  t.OverheatThreshold,
		CriticalThreshold:  t.CriticalThreshold,
		HwStatus:           t.HwStatus,
	}
}

func (s *server) ShowEnvironmentTemperature(ctx context.Context, req *pb.ShowEnvironmentTemperatureRequest) (*pb.ShowEnvironmentTemperatureResponse, error) {
	var response []struct {
		PowerSupplySlots []struct {
			TempSensors      []temperatureSensor `json:"tempSensors"`
			EntPhysicalClass string              `json:"entPhysicalClass"`
			RelPos           string              `json:"relPos"`
		} `json:"powerSupplySlots"`

		ShutdownOnOverheat bool                `json:"shutdownOnOverheat"`
		TempSensors        []temperatureSensor `json:"tempSensors"`
		SystemStatus       string              `json:"systemStatus"`
	}

	err := s.arista.structuredCall(&response, "show environment temperature")
	if err != nil {
		glog.Errorf("EOS Capi: show environment temperature: %v", err)
		return nil, status.Error(codes.Unavailable, "EOS Capi call failed")
	}

	if len(response) != 1 {
		glog.Errorf("Expected 1-length result, got %d", len(response))
		return nil, status.Error(codes.Internal, "Internal error")
	}

	d := response[0]

	res := &pb.ShowEnvironmentTemperatureResponse{
		SystemStatus:       d.SystemStatus,
		ShutdownOnOverheat: d.ShutdownOnOverheat,
		PowerSupplySlots:   make([]*pb.ShowEnvironmentTemperatureResponse_PowerSupplySlot, len(d.PowerSupplySlots)),
		TemperatureSensors: make([]*pb.ShowEnvironmentTemperatureResponse_TemperatureSensor, len(d.TempSensors)),
	}

	for i, t := range d.TempSensors {
		res.TemperatureSensors[i] = t.Proto()
	}

	for i, p := range d.PowerSupplySlots {
		res.PowerSupplySlots[i] = &pb.ShowEnvironmentTemperatureResponse_PowerSupplySlot{
			EntPhysicalClass:   p.EntPhysicalClass,
			RelPos:             p.RelPos,
			TemperatureSensors: make([]*pb.ShowEnvironmentTemperatureResponse_TemperatureSensor, len(p.TempSensors)),
		}
		for j, t := range p.TempSensors {
			res.PowerSupplySlots[i].TemperatureSensors[j] = t.Proto()
		}
	}

	return res, nil
}
