use std::fmt::Display;
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Debug, Copy, Clone, PartialEq, Eq, Default)]
#[serde(rename_all = "lowercase")]
pub enum Modloader {
	#[default]
	Vanilla,
	Forge,
	NeoForged,
	Fabric,
	Quilt,
	LiteLoader,
	Risugamis,
	Rift,
}
impl Display for Modloader {
	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
		match self {
			Self::Vanilla => write!(f, "None"),
			Self::Forge => write!(f, "Forge"),
			Self::NeoForged => write!(f, "NeoForged"),
			Self::Fabric => write!(f, "Fabric"),
			Self::Quilt => write!(f, "Quilt"),
			Self::LiteLoader => write!(f, "LiteLoader"),
			Self::Risugamis => write!(f, "Risugami's"),
			Self::Rift => write!(f, "Rift"),
		}
	}
}
#[derive(Debug, Clone, PartialEq, Eq, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum ModloaderMatch {
	Vanilla,
	Forge,
	NeoForged,
	ForgeLike,
	Fabric,
	Quilt,
	FabricLike,
	LiteLoader,
	Risugamis,
	Rift,
}
impl ModloaderMatch {
	pub fn parse_from_str(string: &str) -> Option<Self> {
		match string {
			"vanilla" => Some(Self::Vanilla),
			"forge" => Some(Self::Forge),
			"neoforged" => Some(Self::NeoForged),
			"forgelike" => Some(Self::ForgeLike),
			"fabric" => Some(Self::Fabric),
			"quilt" => Some(Self::Quilt),
			"fabriclike" => Some(Self::FabricLike),
			"liteloader" => Some(Self::LiteLoader),
			"risugamis" => Some(Self::Risugamis),
			"rift" => Some(Self::Rift),
			_ => None,
		}
	}
	pub fn matches(&self, other: &Modloader) -> bool {
		match self {
			Self::Vanilla => matches!(other, Modloader::Vanilla),
			Self::Forge => matches!(other, Modloader::Forge),
			Self::NeoForged => matches!(other, Modloader::NeoForged),
			Self::ForgeLike => matches!(other, Modloader::Forge | Modloader::NeoForged),
			Self::Fabric => matches!(other, Modloader::Fabric),
			Self::Quilt => matches!(other, Modloader::Quilt),
			Self::FabricLike => matches!(other, Modloader::Fabric | Modloader::Quilt),
			Self::LiteLoader => matches!(other, Modloader::LiteLoader),
			Self::Risugamis => matches!(other, Modloader::Risugamis),
			Self::Rift => matches!(other, Modloader::Rift),
		}
	}
}
#[derive(Serialize, Deserialize, Debug, Copy, Clone, Default)]
#[serde(rename_all = "lowercase")]
pub enum ServerType {
	#[default]
	None,
	Vanilla,
	Paper,
	Sponge,
	SpongeForge,
	CraftBukkit,
	Spigot,
	Glowstone,
	Pufferfish,
	Purpur,
	Folia,
	Forge,
	NeoForged,
	Fabric,
	Quilt,
	Risugamis,
	Rift,
}
impl Display for ServerType {
	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
		match self {
			Self::None => write!(f, "Vanilla"),
			Self::Vanilla => write!(f, "Vanilla"),
			Self::Paper => write!(f, "Paper"),
			Self::Sponge => write!(f, "Sponge"),
			Self::SpongeForge => write!(f, "SpongeForge"),
			Self::CraftBukkit => write!(f, "CraftBukkit"),
			Self::Spigot => write!(f, "Spigot"),
			Self::Glowstone => write!(f, "Glowstone"),
			Self::Pufferfish => write!(f, "Pufferfish"),
			Self::Purpur => write!(f, "Purpur"),
			Self::Folia => write!(f, "Folia"),
			Self::Forge => write!(f, "Forge"),
			Self::NeoForged => write!(f, "NeoForged"),
			Self::Fabric => write!(f, "Fabric"),
			Self::Quilt => write!(f, "Quilt"),
			Self::Risugamis => write!(f, "Risugami's"),
			Self::Rift => write!(f, "Rift"),
		}
	}
}
#[derive(Debug, Clone, PartialEq, Eq, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum PluginLoaderMatch {
	Vanilla,
	Bukkit,
	Paper,
	Sponge,
	CraftBukkit,
	Spigot,
	Glowstone,
	Pufferfish,
	Purpur,
	Folia,
}
impl PluginLoaderMatch {
	pub fn parse_from_str(string: &str) -> Option<Self> {
		match string {
			"vanilla" => Some(Self::Vanilla),
			"bukkit" => Some(Self::Bukkit),
			"paper" => Some(Self::Paper),
			"sponge" => Some(Self::Sponge),
			"craftbukkit" => Some(Self::CraftBukkit),
			"spigot" => Some(Self::Spigot),
			"glowstone" => Some(Self::Glowstone),
			"pufferfish" => Some(Self::Pufferfish),
			"purpur" => Some(Self::Purpur),
			"folia" => Some(Self::Folia),
			_ => None,
		}
	}
	pub fn matches(&self, other: &ServerType) -> bool {
		match self {
			Self::Vanilla => matches!(other, ServerType::Vanilla),
			Self::Bukkit => matches!(
				other,
				ServerType::Paper
					| ServerType::CraftBukkit
					| ServerType::Spigot | ServerType::Glowstone
					| ServerType::Pufferfish
					| ServerType::Purpur
			),
			Self::Paper => matches!(other, ServerType::Paper),
			Self::Sponge => matches!(other, ServerType::Sponge | ServerType::SpongeForge),
			Self::CraftBukkit => matches!(other, ServerType::CraftBukkit),
			Self::Spigot => matches!(other, ServerType::Spigot),
			Self::Glowstone => matches!(other, ServerType::Glowstone),
			Self::Pufferfish => matches!(other, ServerType::Pufferfish),
			Self::Purpur => matches!(other, ServerType::Purpur),
			Self::Folia => matches!(other, ServerType::Folia),
		}
	}
}
#[derive(Serialize, Deserialize, Debug, Copy, Clone, Default)]
#[serde(rename_all = "lowercase")]
pub enum ClientType {
	#[default]
	None,
	Vanilla,
	Forge,
	NeoForged,
	Fabric,
	Quilt,
	LiteLoader,
	Risugamis,
	Rift,
}
impl Display for ClientType {
	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
		match self {
			Self::None => write!(f, "Vanilla"),
			Self::Vanilla => write!(f, "Vanilla"),
			Self::Forge => write!(f, "Forge"),
			Self::NeoForged => write!(f, "NeoForged"),
			Self::Fabric => write!(f, "Fabric"),
			Self::Quilt => write!(f, "Quilt"),
			Self::LiteLoader => write!(f, "LiteLoader"),
			Self::Risugamis => write!(f, "Risugami's"),
			Self::Rift => write!(f, "Rift"),
		}
	}
}