/* DatabaseTracks.h */

/* Copyright (C) 2011-2024 Michael Lugmair (Lucio Carreras)
 *
 * This file is part of sayonara player
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.

 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.

 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef DATABASETRACKS_H
#define DATABASETRACKS_H

#include "Database/Utils.h"
#include "Utils/typedefs.h"
#include <QMap>
#include <functional>

namespace Library
{
	class Filter;
}

class QSqlQuery;
class Genre;
class MetaDataList;

namespace DB
{
	class Module;
	class Tracks
	{
		public:
			Tracks();
			virtual ~Tracks();

			void initViews();

			virtual MetaDataList dbFetchTracks(QSqlQuery& q) const;

			virtual int getNumTracks() const;
			virtual MetaDataList getAllTracks() const;

			virtual MetaDataList getAllTracksByAlbum(const IdList& albumsIds) const;
			virtual MetaDataList getAllTracksByAlbum(const IdList& track, const ::Library::Filter& filter,
			                                         int discnumber) const;
			virtual MetaDataList getAllTracksByArtist(const IdList& artistIds) const;
			virtual MetaDataList getAllTracksByArtist(const IdList& artistIds, const ::Library::Filter& filter) const;
			virtual MetaDataList getAllTracksBySearchString(const ::Library::Filter& filter) const;
			virtual MetaDataList getAllTracksByPaths(const QStringList& paths) const;

			virtual MetaData getTrackById(TrackID id) const;
			virtual MetaData getTrackByPath(const QString& path) const;
			virtual MetaDataList getMultipleTracksByPath(const QStringList& paths) const;

			virtual bool
			insertTrackIntoDatabase(const MetaData& track, ArtistId artistId, AlbumId albumId, ArtistId albumArtistId);
			virtual bool updateTrack(const MetaData& track);

			virtual bool renameFilepaths(const QMap<QString, QString>& paths, LibraryId libraryId);
			virtual bool renameFilepath(const QString& oldPath, const QString& newPath, LibraryId libraryId);

			virtual bool deleteTrack(TrackID id);
			virtual bool deleteTracks(const IdList& ids);

			// some tracks may be inserted two times
			// this function deletes BOTH copies but returns those tracks
			// which were found twice. Those tracks should be inserted by the store_metadata()
			// function of LibraryDatabase
			virtual MetaDataList deleteInvalidTracks(const QString& libraryPath);

			virtual QString fetchQueryTracks(const QString& where) const;

			virtual Util::Set<Genre> getAllGenres() const;

			void deleteAllTracks(bool alsoViews);

		protected:
			[[nodiscard]] virtual QString trackView() const = 0;
			[[nodiscard]] virtual QString trackSearchView() const = 0;
			[[nodiscard]] virtual LibraryId libraryId() const = 0;

			virtual Module* module() = 0;
			virtual const Module* module() const = 0;

			virtual void updateTrackCissearch();

		private:
			MetaData getSingleTrack(const QString& queryText, const std::pair<QString, QVariant>& binding,
			                        const QString& errorMessage) const;
			[[nodiscard]] MetaDataList getAllTracksByIdList(
				const IdList& ids, const ::Library::Filter& filter,
				std::function<bool(const MetaData&, Id)>&& trackMatchesId) const;

			MetaDataList getAllTracks(const ::Library::Filter& filter) const;
	};
}

#endif // DATABASETRACKS_H
