/*
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
 */

#pragma once

#include "Base/Utils.hpp"
#include <string_view>
#include <optional>

namespace OpenVulkano
{
	class ArchiveType final
	{
		static inline constexpr std::string_view TYPE_NAMES[] = { ".tar", ".cpio", ".iso", ".zip", ".xar", ".7z", ".warc", ".shar" };

	public:
		enum Type { TAR = 0, CPIO, ISO, ZIP, XAR, SEVEN_ZIP, WARC, SHAR };

		constexpr ArchiveType(Type type) : m_type(type) {}

		[[nodiscard]] constexpr bool AllowsUnknownFileSize() const { return m_type == ZIP; }

		[[nodiscard]] constexpr bool AllowsMixedCompressionLevels() const { return m_type == ZIP; }

		[[nodiscard]] constexpr std::string_view GetExtension() const { return TYPE_NAMES[m_type]; }

		[[nodiscard]] constexpr bool operator==(Type rhs) const { return m_type == rhs; }
		[[nodiscard]] constexpr bool operator==(ArchiveType rhs) const { return m_type == rhs.m_type; }
		[[nodiscard]] constexpr bool operator!=(Type rhs) const { return m_type != rhs; }
		[[nodiscard]] constexpr bool operator!=(ArchiveType rhs) const { return m_type != rhs.m_type; }

		[[nodiscard]] constexpr explicit operator int() const { return m_type; }
		[[nodiscard]] constexpr operator Type() const { return m_type; }

		[[nodiscard]] static constexpr std::optional<ArchiveType> FromExtension(std::string_view fName)
		{
			int tId = 0;
			for(const std::string_view& tName : TYPE_NAMES)
			{
				if (tId > 0)
				{
					if (Utils::EndsWith(fName, tName))
					{
						return static_cast<Type>(tId);
					}
				}
				tId++;
			}
			return std::nullopt;
		}

	private:
		Type m_type;
	};
}