package media

//go:generate mockery --recursive --name Store --output ../generated/mocks
//go:generate mockery --recursive --name YoutubeClient --output ../generated/mocks
//go:generate mockery --recursive --name FileStore --output ../generated/mocks

import (
	"context"
	"io"
	"time"

	"git.netflux.io/rob/clipper/generated/store"
	"github.com/google/uuid"
	youtubev2 "github.com/kkdai/youtube/v2"
)

// An int16 has two bytes.
const SizeOfInt16 = 2

// MediaSet represents the media and metadata associated with a single media
// resource (for example, a YouTube video).
type MediaSet struct {
	Audio                      Audio
	Video                      Video
	ID                         uuid.UUID
	YoutubeID                  string
	Title, Description, Author string
}

// Audio contains the metadata for the audio part of the media set.
type Audio struct {
	ContentLength int64
	Channels      int
	// ApproxFrames is used during initial processing when a precise frame count
	// cannot be determined. Prefer Frames in all other cases.
	ApproxFrames int64
	Frames       int64
	SampleRate   int
	YoutubeItag  int
	MimeType     string
}

// Video contains the metadata for the video part of the media set.
type Video struct {
	ContentLength int64
	Duration      time.Duration
	// not sure if this are needed any more?
	ThumbnailWidth  int
	ThumbnailHeight int
	YoutubeItag     int
	MimeType        string
}

// Store wraps a database store.
type Store interface {
	GetMediaSet(context.Context, uuid.UUID) (store.MediaSet, error)
	GetMediaSetByYoutubeID(context.Context, string) (store.MediaSet, error)
	CreateMediaSet(context.Context, store.CreateMediaSetParams) (store.MediaSet, error)
	SetRawAudioUploaded(context.Context, store.SetRawAudioUploadedParams) (store.MediaSet, error)
	SetEncodedAudioUploaded(context.Context, store.SetEncodedAudioUploadedParams) (store.MediaSet, error)
	SetVideoUploaded(context.Context, store.SetVideoUploadedParams) (store.MediaSet, error)
	SetVideoThumbnailUploaded(context.Context, store.SetVideoThumbnailUploadedParams) (store.MediaSet, error)
}

// FileStore wraps a file store.
type FileStore interface {
	GetObject(ctx context.Context, key string) (io.ReadCloser, error)
	GetObjectWithRange(ctx context.Context, key string, startFrame, endFrame int64) (io.ReadCloser, error)
	GetURL(ctx context.Context, key string) (string, error)
	PutObject(ctx context.Context, key string, reader io.Reader, contentType string) (int64, error)
}

// YoutubeClient wraps the youtube.Client client.
type YoutubeClient interface {
	GetVideoContext(ctx context.Context, id string) (*youtubev2.Video, error)
	GetStreamContext(ctx context.Context, video *youtubev2.Video, format *youtubev2.Format) (io.ReadCloser, int64, error)
}
