package db

import (
	"context"
	"errors"

	"go.uber.org/zap/zapcore"
)

// ErrServiceNotFound TODO: remove?
var ErrServiceNotFound = errors.New("service not found")

type Service struct {
	ID               int    `json:"id" db:"id"`
	ServiceCatalogID string `json:"service_catalog_id" db:"service_catalog_id"`
	Name             string `json:"name" db:"name"`
	LDAPGroup        string `json:"ldap_group" db:"ldap_group"`
	Description      string `json:"description" db:"description"`
	Accounts         []*Account
	IAMRoles         []*IAMRole
}

func (s Service) Editable() ServiceEditable {
	return ServiceEditable{
		ServiceCatalogID: s.ServiceCatalogID,
		Name:             s.Name,
		LDAPGroup:        s.LDAPGroup,
		Description:      s.Description,
	}
}

func (s Service) MarshalLogObject(enc zapcore.ObjectEncoder) error {
	enc.AddInt("id", s.ID)
	enc.AddString("name", s.Name)
	enc.AddString("description", s.Description)
	enc.AddString("serviceCatalogID", s.ServiceCatalogID)
	enc.AddString("ldapGroup", s.LDAPGroup)
	return nil
}

type ServiceEditable struct {
	ServiceCatalogID string `json:"service_catalog_id" db:"service_catalog_id"`
	Name             string `json:"name" db:"name"`
	LDAPGroup        string `json:"ldap_group" db:"ldap_group"`
	Description      string `json:"description" db:"description"`
}

func (se ServiceEditable) MarshalLogObject(enc zapcore.ObjectEncoder) error {
	enc.AddString("name", se.Name)
	enc.AddString("description", se.Description)
	enc.AddString("serviceCatalogID", se.ServiceCatalogID)
	enc.AddString("ldapGroup", se.LDAPGroup)
	return nil
}

type ServicesDB interface {
	ServiceCreate(ctx context.Context, service *Service) (int, error)

	ServiceUpdate(ctx context.Context, id int, serviceEditable *ServiceEditable) (int, error)
	ServiceDelete(ctx context.Context, id int) error

	Services(ctx context.Context) ([]*Service, error)
	ServiceByID(ctx context.Context, id int) (*Service, error)
	ServiceByServiceCatalogID(ctx context.Context, id string) (*Service, error)
	ServicesByLDAPGroup(ctx context.Context, ldap string) ([]*Service, error)
	ServicesWithIAMRoles(ctx context.Context) ([]*Service, error)

	//CanPublish(ctx context.Context, eventStreamID int) ([]*Account, error)
}
