{{
    const dotUtils = require('./dotUtils.js');
    const champions = require('./.champion.json')
        .filter(({ id }) => id > 0)
        .sortBy(({ name }) => name);
    const hashFactor = 256;
    const enumName = name => name.replace(/[^a-z]+/i, '');
    const strHash = function(str) {
        let h = 0;
        for (let c of str)
            h = hashFactor * h + c.charCodeAt(0);
        return h;
    };
    const padId = function(id) { return ('' + id).padEnd(3); };
}}{{= dotUtils.preamble() }}

use num_enum::{ IntoPrimitive, TryFromPrimitive };
use serde_repr::{ Serialize_repr, Deserialize_repr };
use strum_macros::{ EnumString, EnumIter, Display, AsRefStr, IntoStaticStr };

/// League of Legend's champions.
///
/// The documentation of each variant specifies:<br>
/// NAME (`IDENTIFIER`, ID).
///
/// Implements [IntoEnumIterator](super::IntoEnumIterator).
#[cfg_attr(feature = "nightly", non_exhaustive)]
#[derive(Debug, Copy, Clone)]
#[derive(IntoPrimitive, TryFromPrimitive)]
#[derive(Serialize_repr, Deserialize_repr)]
#[derive(EnumString, EnumIter, Display, AsRefStr, IntoStaticStr)]
#[repr(i16)]
pub enum Champion {
    /// A champion that doesn't exist. Used in TeamBans when no champion was banned.
    ///
    /// None (`NONE`, -1).
    None = -1,

{{
    for (let { id, alias, name } of champions) {
}}
    /// {{= name }} (`{{= alias }}`, {{= id }}).
    #[strum(to_string="{{= name }}", serialize="{{= alias }}")] {{= enumName(name) }} = {{= id }},
{{
    }
}}
}

impl Champion {
    /// The champion's name (localized `en_US`), or `"NONE"` for the None variant.
    pub fn name(self) -> &'static str {
        self.into()
    }

    /// The champion's identifier key. Somtimes called "key", "identifier", or "alias".
    /// This is mainly used in DDragon paths.
    ///
    /// This is generally the `en_US` name with spaces and punctuation removed,
    /// but there are the following exceptions:
    ///
    /// Variant | Name | Identifier
    /// --------|------|-----------
    /// `None` | "NONE" | "NONE"
{{
    for (let { name, alias } of champions) {
        if (name.replace(/[^a-zA-Z0-9]+/, '') !== alias) {
}}
    /// `{{= enumName(name) }}` | "{{= name }}" | "{{= alias }}"
{{
        }
    }
}}
    pub fn identifier(self) -> &'static str {
        match self {
            Self::None         => "NONE",
{{
    for (let { name, alias } of champions) {
}}
            Self::{{= enumName(name).padEnd(12) }} => "{{= alias }}",
{{
    }
}}
        }
    }
}