use std::fmt;

/// A lite protocol version.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum Version {
	Lite01,
	Lite02,
	Lite03,
	Lite04,
	/// Work-in-progress placeholder for lite-05. Not advertised over ALPN or
	/// included in default version sets; callers must opt in explicitly.
	Lite05Wip,
}

impl Version {
	/// Whether this version uses a unidirectional Setup stream (moq-lite-05+).
	///
	/// Earlier versions negotiate purely via ALPN and exchange no SETUP message.
	pub fn has_setup_stream(self) -> bool {
		matches!(self, Self::Lite05Wip)
	}

	/// Whether this version uses the moq-lite-05 framing bundle: the Track stream
	/// (TRACK/TRACK_INFO), a SUBSCRIBE_OK trimmed to the resolved start group plus a
	/// distinct SUBSCRIBE_END, and a per-frame timestamp delta. Earlier versions carry
	/// publisher properties inline in SUBSCRIBE_OK and frames without a timestamp.
	pub fn has_track_stream(self) -> bool {
		matches!(self, Self::Lite05Wip)
	}
}

impl fmt::Display for Version {
	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
		match self {
			Self::Lite01 => write!(f, "moq-lite-01"),
			Self::Lite02 => write!(f, "moq-lite-02"),
			Self::Lite03 => write!(f, "moq-lite-03"),
			Self::Lite04 => write!(f, "moq-lite-04"),
			Self::Lite05Wip => write!(f, "moq-lite-05-wip"),
		}
	}
}

impl From<Version> for crate::Version {
	fn from(v: Version) -> Self {
		match v {
			Version::Lite01 => crate::Version::Lite(Version::Lite01),
			Version::Lite02 => crate::Version::Lite(Version::Lite02),
			Version::Lite03 => crate::Version::Lite(Version::Lite03),
			Version::Lite04 => crate::Version::Lite(Version::Lite04),
			Version::Lite05Wip => crate::Version::Lite(Version::Lite05Wip),
		}
	}
}

impl TryFrom<crate::Version> for Version {
	type Error = ();

	fn try_from(v: crate::Version) -> Result<Self, Self::Error> {
		match v {
			crate::Version::Lite(v) => Ok(v),
			crate::Version::Ietf(_) => Err(()),
		}
	}
}
