/*
 * Copyright (C) 2011-2024 Michael Lugmair
 *
 * 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/>.
 */

#include "PlaylistTestUtils.h"

#include "Common/SayonaraTest.h"
#include "Common/PlayManagerMock.h"
#include "Common/FileSystemMock.h"

#include "Components/Playlist/Playlist.h"
#include "Components/Playlist/PlaylistModifiers.h"
#include "Utils/MetaData/MetaDataList.h"
#include "Utils/Playlist/PlaylistMode.h"
#include "Utils/Settings/Settings.h"

// access working directory with Test::Base::tempPath("somefile.txt");

namespace
{
	::Playlist::Playlist* createPlaylist(const Playlist::Mode& mode, const int count = 10)
	{
		SetSetting(Set::PL_Mode, mode);

		auto playManager = new Test::PlayManagerMock();
		const auto fileSystem = std::make_shared<Test::AllFilesAvailableFileSystem>();

		auto* playlist = new Playlist::Playlist(1, "a", playManager, fileSystem);
		playlist->createPlaylist(Test::Playlist::createTrackList(0, count));

		return playlist;
	}
}

class RepeatTest :
	public Test::Base
{
	Q_OBJECT

	public:
		RepeatTest() :
			Test::Base("RepeatTest") {}

	private slots:

		// NOLINTNEXTLINE(readability-convert-member-functions-to-static)
		[[maybe_unused]] void testPlaylistStopsAfterLastTrack()
		{
			Playlist::Mode mode;
			mode.setRepAll(Playlist::Mode::State::Off);

			auto* playlist = createPlaylist(mode);
			for(auto i = 0; i < playlist->count(); i++)
			{
				playlist->next();
				QVERIFY(playlist->findCurrentTrackIndex() >= 0);
			}

			playlist->next();
			QVERIFY(playlist->findCurrentTrackIndex() < 0);
		}

		// NOLINTNEXTLINE(readability-convert-member-functions-to-static)
		[[maybe_unused]] void testRepeatAll()
		{
			Playlist::Mode mode;
			mode.setRepAll(Playlist::Mode::State::On);

			auto* playlist = createPlaylist(mode);
			for(auto i = 0; i < playlist->count() * 3; i++)
			{
				playlist->next();
				QVERIFY(playlist->findCurrentTrackIndex() >= 0);
			}
		}

		// NOLINTNEXTLINE(readability-convert-member-functions-to-static)
		[[maybe_unused]] void testRepeatOne()
		{
			constexpr const auto TrackCount = 10;
			constexpr const auto TestCases = std::array {2, 5};

			Playlist::Mode mode;
			mode.setRep1(Playlist::Mode::State::On);

			auto* playlist = createPlaylist(mode, TrackCount);

			for(const auto& changedIndex: TestCases)
			{
				playlist->changeTrack(changedIndex);
				QVERIFY(playlist->findCurrentTrackIndex() == changedIndex);

				for(auto i = 0; i < TrackCount; i++)
				{
					playlist->next();
					QVERIFY(playlist->findCurrentTrackIndex() == changedIndex);
				}
			}
		}
};

QTEST_GUILESS_MAIN(RepeatTest)

#include "RepeatTest.moc"
