package db

import (
	"context"
	"database/sql"
	"errors"

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

// ErrPublicationNotFound TODO: remove?
var ErrPublicationNotFound = errors.New("publication not found")

type Publication struct {
	ID            int           `json:"id" db:"id"`
	AccountID     sql.NullInt64 `json:"account_id" db:"account_id"`
	IAMRoleID     sql.NullInt64 `json:"iam_role_id" db:"iam_role_id"`
	EventStreamID int           `json:"event_stream_id" db:"event_stream_id"`
}

func (p *Publication) Equals(other *Publication) bool {
	return (p.AccountID.Valid && other.AccountID.Valid &&
		p.AccountID.Int64 == other.AccountID.Int64) ||
		(p.IAMRoleID.Valid && other.IAMRoleID.Valid &&
			p.IAMRoleID.Int64 == other.IAMRoleID.Int64)
}

type PublicationsDB interface {
	PublicationCreate(ctx context.Context, publication *Publication) (int, error)

	PublicationDelete(ctx context.Context, id int) error
	PublicationDeleteByEventStreamID(ctx context.Context, eventStreamID int) error

	Publications(ctx context.Context) ([]*Publication, error)
	PublicationsByServiceID(ctx context.Context, serviceID int) ([]*Publication, error)
	PublicationsByEventStreamID(ctx context.Context, eventStreamID int) ([]*Publication, error)
	PublicationsByIAMRoleID(ctx context.Context, iamRoleID int) ([]*Publication, error)
}

func (p Publication) MarshalLogObject(enc zapcore.ObjectEncoder) error {
	enc.AddInt("ID", p.ID)
	if p.AccountID.Valid {
		enc.AddInt64("accountID", p.AccountID.Int64)
	}
	if p.IAMRoleID.Valid {
		enc.AddInt64("iamRoleID", p.IAMRoleID.Int64)
	}
	enc.AddInt("eventStreamID", p.EventStreamID)
	return nil
}
