package main

import (
	"context"

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

	pb "code.hackerspace.pl/q3k/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             int64   `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 (s *server) ShowEnvironmentTemperature(ctx context.Context, req *pb.ShowEnvironmentTemperatureRequest) (*pb.ShowEnvironmentTemperatureResponse, error) {
	var response []struct {
		PowerSuppplySlots []struct {
			TempSensors      []temperatureSensor `json:"tempSensors"`
			EntPhysicalClass string              `json:"entPhysicalClass"`
			RelPos           int64               `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]
	glog.Infof("%+v", d)

	return &pb.ShowEnvironmentTemperatureResponse{}, nil
}
