package server

import (
	"code.justin.tv/creator-collab/log"
	"code.justin.tv/creator-collab/log/errors"
	"code.justin.tv/live/plucky/api/db"
	"code.justin.tv/live/plucky/api/rpc"
	"code.justin.tv/live/plucky/api/util"
)

var AllServices = map[string]bool{
	ServiceIDAutohost:       true,
	ServiceIDNexus:          true,
	ServiceIDShelfie:        true,
	ServiceIDStreamSchedule: true,
}

type Server struct {
	cwlogsClient *CWLogs
	logger       log.Logger
	services     map[string]*Service
	database     *db.DB
	clock        util.Clock
	version      string
	gitCommit    string
}

// Server implements the Plucky interface.
var _ rpc.Plucky = &Server{}

type ServerConfig struct {
	Services  []*Service
	Level     util.LogLevel
	Version   string
	GitCommit string
}

func NewServer(config *ServerConfig) (*Server, error) {
	logger := util.NewLogger(config.Level)

	cwlogsClient, err := NewCWLogs()
	if err != nil {
		return nil, err
	}

	database, err := db.New(logger)
	if err != nil {
		return nil, err
	}

	clock := util.NewRealClock()

	serviceMap := make(map[string]*Service, len(config.Services))
	for _, service := range config.Services {
		serviceMap[service.ID] = service
	}

	return &Server{
		cwlogsClient: cwlogsClient,
		logger:       logger,
		services:     serviceMap,
		database:     database,
		clock:        clock,
		version:      config.Version,
		gitCommit:    config.GitCommit,
	}, nil
}

func (s *Server) getService(serviceID, stageID string) (*Service, error) {
	for _, service := range s.services {
		if service.ID == serviceID && service.StageID == stageID {
			return service, nil
		}
	}
	return nil, errors.New("server does not have given service", errors.Fields{
		"service_id": serviceID,
		"stage_id":   stageID,
	})
}
