package server

import (
	"fmt"

	"git.ctrlz.es/mgdelacroix/craban/model"
	"git.ctrlz.es/mgdelacroix/craban/services/store"
	"git.ctrlz.es/mgdelacroix/craban/web"
)

type Server struct {
	Config *model.Config

	Store     *store.Store
	WebServer *web.WebServer
}

func NewServer(config *model.Config) (*Server, error) {
	if err := config.IsValid(); err != nil {
		return nil, fmt.Errorf("config is not valid: %w", err)
	}

	webserver, err := web.NewWebServer(*config.Port)
	if err != nil {
		return nil, fmt.Errorf("cannot create webserver: %w", err)
	}

	store, err := store.NewStore(*config.DatabasePath)
	if err != nil {
		return nil, fmt.Errorf("cannot create store: %w", err)
	}

	return &Server{
		Config:    config,
		WebServer: webserver,
		Store:     store,
	}, err
}

func NewServerWithConfigPath(path string) (*Server, error) {
	config, err := model.ReadConfig(path)
	if err != nil {
		return nil, fmt.Errorf("cannot read config from path %q: %w", path, err)
	}

	return NewServer(config)
}

func (s *Server) Start() error {
	if err := s.WebServer.Start(); err != nil {
		return fmt.Errorf("error starting webserver: %w", err)
	}
	return nil
}

func (s *Server) Close() error {
	if err := s.WebServer.Close(); err != nil {
		return fmt.Errorf("error stopping webserver: %w", err)
	}

	if err := s.Store.Close(); err != nil {
		return fmt.Errorf("error stopping store: %w", err)
	}

	return nil
}
