/*
 * 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 "Components/Directories/DirectorySelectionHandler.h"
#include "Components/LibraryManagement/LibraryManager.h"
#include "Utils/Library/LibraryInfo.h"

#include "Utils/Algorithm.h"

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

namespace
{
	class TestLibraryManager :
		public Library::Manager
	{
		public:
			explicit TestLibraryManager(const QList<Library::Info>& infos) :
				m_infos {infos} {}

			~TestLibraryManager() override = default;

			LibraryId addLibrary(const QString& /*name*/, const QString& /*path*/) override
			{
				throw std::runtime_error {"Not implemented"};
			}

			bool renameLibrary(LibraryId /*id*/, const QString& /*newName*/) override
			{
				throw std::runtime_error {"Not implemented"};
			}

			bool removeLibrary(LibraryId /*id*/) override
			{
				throw std::runtime_error {"Not implemented"};
			}

			bool moveLibrary(int /*oldRow*/, int /*newRow*/) override
			{
				throw std::runtime_error {"Not implemented"};
			}

			bool changeLibraryPath(LibraryId /*id*/, const QString& /*newPath*/) override
			{
				throw std::runtime_error {"Not implemented"};
			}

			[[nodiscard]] QList<Library::Info> allLibraries() const override
			{
				return m_infos;
			}

			[[nodiscard]] Library::Info libraryInfo(const LibraryId id) const override
			{
				const auto index = Util::Algorithm::indexOf(m_infos, [&](const auto& info) {
					return info.id() == id;
				});

				return Util::between(index, m_infos)
				       ? m_infos[index]
				       : Library::Info {};
			}

			[[nodiscard]] Library::Info libraryInfoByPath(const QString& path) const override
			{
				const auto index = Util::Algorithm::indexOf(m_infos, [&](const auto& info) {
					return info.path() == path;
				});

				return Util::between(index, m_infos)
				       ? m_infos[index]
				       : Library::Info {};
			}

			int count() const override { return m_infos.count(); }

			LocalLibrary* libraryInstance(LibraryId /*id*/) override
			{
				throw std::runtime_error {"Not implemented"};
			}

		private:
			QList<Library::Info> m_infos;
	};

	QList<Library::Info> createInfos(const std::map<LibraryId, QString>& idPathMap)
	{
		auto result = QList<Library::Info> {};

		for(const auto& [id, path]: idPathMap)
		{
			result << Library::Info {path, path, id};
		}

		return result;
	}
}

class DirectorySelectionHandlerTest :
	public Test::Base
{
	Q_OBJECT

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

	private slots:

		// NOLINTNEXTLINE(readability-convert-member-functions-to-static)
		[[maybe_unused]] void testLibraryIdIsParsedCorrectly()
		{

			const auto infos = createInfos({
				                               {1, "/path/to/1"},
				                               {2, "/path/to/2"},
			                               });

			auto libraryManager = TestLibraryManager {infos};

			struct TestCase
			{
				LibraryId libraryId;
				LibraryId expectedLibraryId;
			};

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

			for(const auto& testCase: testCases)
			{
				auto dsh = DirectorySelectionHandler {&libraryManager};
				dsh.setLibraryId(testCase.libraryId);

				QVERIFY(dsh.libraryId() == testCase.expectedLibraryId);
			}
		}
};

QTEST_GUILESS_MAIN(DirectorySelectionHandlerTest)

#include "DirectorySelectionHandlerTest.moc"
