package service import ( "context" "errors" "github.com/metadata-agregator/internal/domain" "github.com/metadata-agregator/internal/provider" "github.com/metadata-agregator/internal/repository" ) type MetadataService struct { artists repository.ArtistRepository albums repository.AlbumRepository tracks repository.TrackRepository provider provider.Provider } func NewMetadataService( artists repository.ArtistRepository, albums repository.AlbumRepository, tracks repository.TrackRepository, prov provider.Provider, ) *MetadataService { return &MetadataService{ artists: artists, albums: albums, tracks: tracks, provider: prov, } } func (s *MetadataService) GetArtist(ctx context.Context, id string) (*domain.Artist, error) { artist, err := s.artists.GetByExternalID(ctx, s.provider.Name(), id) if err == nil { return artist, nil } if !errors.Is(err, repository.ErrNotFound) { return nil, err } artist, err = s.provider.GetArtist(ctx, id) if err != nil { return nil, err } if saveErr := s.artists.Save(ctx, artist); saveErr != nil { return artist, nil } return artist, nil } func (s *MetadataService) SearchArtists(ctx context.Context, query string, limit, offset int) (*domain.SearchResult[domain.Artist], error) { result, err := s.artists.Search(ctx, query, limit, offset) if err == nil && len(result.Items) > 0 { return result, nil } return s.provider.SearchArtists(ctx, query, limit, offset) } func (s *MetadataService) SearchAlbums(ctx context.Context, query string, artist string, limit, offset int) (*domain.SearchResult[domain.Album], error) { return s.provider.SearchAlbums(ctx, query, artist, limit, offset) } func (s *MetadataService) GetAlbum(ctx context.Context, id string) (*domain.Album, error) { album, err := s.albums.GetByExternalID(ctx, s.provider.Name(), id) if err == nil { return album, nil } if !errors.Is(err, repository.ErrNotFound) { return nil, err } album, err = s.provider.GetAlbum(ctx, id) if err != nil { return nil, err } if saveErr := s.albums.Save(ctx, album); saveErr != nil { return album, nil } return album, nil } func (s *MetadataService) GetArtistAlbums(ctx context.Context, artistID string, limit, offset int) (*domain.SearchResult[domain.Album], error) { result, err := s.albums.GetByArtistID(ctx, artistID, limit, offset) if err == nil && len(result.Items) > 0 { return result, nil } return s.provider.GetArtistAlbums(ctx, artistID, limit, offset) } func (s *MetadataService) GetTrack(ctx context.Context, id string) (*domain.Track, error) { track, err := s.tracks.GetByExternalID(ctx, s.provider.Name(), id) if err == nil { return track, nil } if !errors.Is(err, repository.ErrNotFound) { return nil, err } track, err = s.provider.GetTrack(ctx, id) if err != nil { return nil, err } if saveErr := s.tracks.Save(ctx, track); saveErr != nil { return track, nil } return track, nil } func (s *MetadataService) GetTrackByISRC(ctx context.Context, isrc string) (*domain.Track, error) { track, err := s.tracks.GetByISRC(ctx, isrc) if err == nil { return track, nil } if !errors.Is(err, repository.ErrNotFound) { return nil, err } track, err = s.provider.GetTrackByISRC(ctx, isrc) if err != nil { return nil, err } if saveErr := s.tracks.Save(ctx, track); saveErr != nil { return track, nil } return track, nil } func (s *MetadataService) GetAlbumTracks(ctx context.Context, albumID string) ([]domain.Track, error) { tracks, err := s.tracks.GetByAlbumID(ctx, albumID) if err == nil && len(tracks) > 0 { return tracks, nil } return s.provider.GetAlbumTracks(ctx, albumID) }