package state

import (
	"context"
	"fmt"
	"sync"

	"google.golang.org/grpc"

	cpb "code.hackerspace.pl/hscloud/go/svc/topo/proto/config"
	pb "code.hackerspace.pl/hscloud/go/svc/topo/proto/control"

	"code.hackerspace.pl/hscloud/go/pki"
)

type SwitchportState struct {
	Proto *pb.SwitchPort
}

type SwitchState struct {
	Name  string
	Ports []*SwitchportState
	Stub  pb.SwitchControlClient
}

func (s *SwitchState) Fetch(ctx context.Context) error {
	req := pb.GetPortsRequest{}
	res, err := s.Stub.GetPorts(ctx, &req)
	if err != nil {
		return fmt.Errorf("GetPorts: %v", err)
	}
	s.Ports = make([]*SwitchportState, len(res.Ports))
	for i, port := range res.Ports {
		s.Ports[i] = &SwitchportState{port}
	}
	return nil
}

type StateManager struct {
	Switches map[string]*SwitchState
	Conns    map[string]*grpc.ClientConn
	Mu       sync.RWMutex
}

func NewManager() *StateManager {
	return &StateManager{
		Switches: make(map[string]*SwitchState),
		Conns:    make(map[string]*grpc.ClientConn),
	}
}

func (s *StateManager) FetchState(ctx context.Context, conf *cpb.Config) error {
	s.Mu.Lock()
	defer s.Mu.Unlock()
	for _, sw := range conf.Switch {
		conn, ok := s.Conns[sw.ControlAddress]
		if !ok {
			var err error
			conn, err = grpc.Dial(sw.ControlAddress, pki.WithClientHSPKI())
			if err != nil {
				return fmt.Errorf("when connecting to switch %s: %v", sw.Name, err)
			}
			s.Conns[sw.ControlAddress] = conn
		}

		s.Switches[sw.Name] = &SwitchState{
			Name: sw.Name,
			Stub: pb.NewSwitchControlClient(conn),
		}
		err := s.Switches[sw.Name].Fetch(ctx)
		if err != nil {
			return fmt.Errorf("%q.Fetch: %v", sw.Name, err)
		}
	}
	return nil
}
