/*
 * 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 "Common/SayonaraTest.h"
#include "Common/FileSystemMock.h"
#include "Playlist/PlaylistTestUtils.h"
#include "Components/Playlist/Playlist.h"
#include "Components/Playlist/PlaylistStopBehavior.h"

#include "Utils/Set.h"

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

class StopBehaviorTest :
	public Test::Base
{
	Q_OBJECT

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

	private slots:

		// NOLINTNEXTLINE(readability-convert-member-functions-to-static)
		[[maybe_unused]] void testInvalidTrackIndexIsNotStoredProperly()
		{
			struct TestCase
			{
				int index;
				int expectedIndex;
			};

			constexpr const auto TracksInPlaylist = 3;

			const auto testCases = std::array {
				TestCase {0, 0},
				TestCase {1, 1},
				TestCase {TracksInPlaylist + 1, -1}
			};

			for(const auto& testCase: testCases)
			{
				auto testEnv = Test::Playlist::TestEnv<Test::AllFilesAvailableFileSystem>(TracksInPlaylist);
				auto stopBehavior = ::Playlist::StopBehavior(&testEnv.playlist);
				stopBehavior.setTrackIndexBeforeStop(testCase.index);

				QVERIFY(stopBehavior.trackIndexBeforeStop() == testCase.expectedIndex);
			}
		}

		// NOLINTNEXTLINE(readability-convert-member-functions-to-static)
		[[maybe_unused]] void removalOfTrackChangesIndex()
		{
			struct TestCase
			{
				int index;
				int indexOfTrackToRemove;
				int expectedIndex;
			};

			constexpr const auto TracksInPlaylist = 5;

			const auto testCases = std::array {
				TestCase {0, 2, 0},
				TestCase {2, 0, 1},
				TestCase {2, 2, -1}
			};

			for(const auto& testCase: testCases)
			{
				auto testEnv = Test::Playlist::TestEnv<Test::AllFilesAvailableFileSystem>(TracksInPlaylist);
				auto stopBehavior = ::Playlist::StopBehavior(&testEnv.playlist);
				stopBehavior.setTrackIndexBeforeStop(testCase.index);
				::Playlist::removeTracks(testEnv.playlist,
				                         {testCase.indexOfTrackToRemove},
				                         ::Playlist::Reason::UserInterface);

				QVERIFY(stopBehavior.trackIndexBeforeStop() == testCase.expectedIndex);
			}
		}

		// NOLINTNEXTLINE(readability-convert-member-functions-to-static)
		[[maybe_unused]] void movingOfTracksChangesIndex()
		{
			struct TestCase
			{
				int index;
				int indexFrom;
				int indexTo;
				int expectedIndex;
			};

			constexpr const auto TracksInPlaylist = 5;

			const auto testCases = std::array {
				TestCase {0, 2, 3, 0},
				TestCase {2, 0, 1, 2},
				TestCase {2, 0, 3, 1},
				TestCase {2, 3, 0, 3},
			};

			for(const auto& testCase: testCases)
			{
				auto testEnv = Test::Playlist::TestEnv<Test::AllFilesAvailableFileSystem>(TracksInPlaylist);
				auto stopBehavior = ::Playlist::StopBehavior(&testEnv.playlist);
				stopBehavior.setTrackIndexBeforeStop(testCase.index);
				::Playlist::moveTracks(testEnv.playlist,
				                       {testCase.indexFrom},
				                       testCase.indexTo,
				                       ::Playlist::Reason::UserInterface);

				QVERIFY(stopBehavior.trackIndexBeforeStop() == testCase.expectedIndex);
			}
		}
};

QTEST_GUILESS_MAIN(StopBehaviorTest)

#include "StopBehaviorTest.moc"
