/*
 * (C) Copyright 2025- ECMWF and individual contributors.
 *
 * This software is licensed under the terms of the Apache Licence Version 2.0
 * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
 * In applying this licence, ECMWF does not waive the privileges and immunities
 * granted to it by virtue of its status as an intergovernmental organisation nor
 * does it submit to any jurisdiction.
 */

///
/// @file representationEnum.h
/// @brief Definition of the `representation` concept variants and compile-time metadata.
///
/// This header defines the **static description** of the GRIB `representation`
/// concept used by the mars2grib backend. It contains:
///
/// - the canonical concept name (`representationName`)
/// - the exhaustive enumeration of supported spatial representations (`RepresentationType`)
/// - a compile-time typelist of all variants (`RepresentationList`)
/// - a compile-time mapping from variant to string identifier
///
/// This file intentionally contains **no runtime logic** and **no encoding
/// behavior**. Its sole purpose is to provide compile-time metadata used by:
///
/// - the concept registry
/// - compile-time table generation
/// - logging and diagnostics
/// - static validation of concept variants
///
/// @note
/// This header is part of the **concept definition layer**.
/// Runtime behavior is implemented separately in the corresponding
/// `representationEncoding.h` implementation.
///
/// @ingroup mars2grib_backend_concepts
///
#pragma once

// System includes
#include <cstdint>
#include <string_view>

// Core concept includes
#include "metkit/mars2grib/backend/compile-time-registry-engine/common.h"
#include "metkit/mars2grib/utils/generalUtils.h"


namespace metkit::mars2grib::backend::concepts_ {

template <auto... Vals>
using ValueList = metkit::mars2grib::backend::compile_time_registry_engine::ValueList<Vals...>;


///
/// @brief Canonical name of the `representation` concept.
///
/// This identifier is used:
/// - as the logical concept key in the concept registry
/// - for logging and debugging output
/// - to associate variants and capabilities with the `representation` concept
///
/// The value must remain stable across releases.
///
inline constexpr std::string_view representationName{"representation"};


///
/// @brief Enumeration of all supported `representation` concept variants.
///
/// Each enumerator represents a distinct spatial grid or spectral
/// representation used to encode meteorological fields.
///
/// The numeric values of the enumerators are **not semantically relevant**;
/// they are required only to:
/// - provide a stable compile-time identifier
/// - allow array indexing and table generation
///
/// @note
/// This enumeration includes structured grids, spectral representations,
/// and unstructured meshes used by atmosphere and ocean models.
///
/// @warning
/// Do not reorder existing enumerators, as they are used in compile-time
/// tables and registries.
///
enum class RepresentationType : std::size_t {
    Latlon = 0,
    RegularGaussian,
    ReducedGaussian,
    SphericalHarmonics,
    GeneralUnstructured,
    Healpix,
    Orca,
    Fesom,
    Dummy,  // Used to skip section3 resolution and delegate to gridSpec
    Default
};


///
/// @brief Compile-time list of all `representation` concept variants.
///
/// This typelist is used to:
/// - generate concept capability tables at compile time
/// - register all supported variants in the concept registry
/// - enable static iteration over variants without runtime overhead
///
/// @note
/// The order of this list must match the intended iteration order
/// for registry construction and diagnostics.
///
using RepresentationList =
    ValueList<RepresentationType::Latlon, RepresentationType::RegularGaussian, RepresentationType::ReducedGaussian,
              RepresentationType::SphericalHarmonics, RepresentationType::GeneralUnstructured,
              RepresentationType::Healpix, RepresentationType::Orca, RepresentationType::Fesom,
              RepresentationType::Dummy, RepresentationType::Default>;


///
/// @brief Compile-time mapping from `RepresentationType` to human-readable name.
///
/// This function returns the canonical string identifier associated
/// with a given representation variant.
///
/// The returned value is used for:
/// - logging and debugging output
/// - error reporting
/// - concept registry diagnostics
///
/// @tparam T Representation variant
/// @return String view identifying the variant
///
/// @note
/// The returned string must remain stable across releases, as it may
/// appear in logs, tests, and diagnostic output.
///
template <RepresentationType T>
constexpr std::string_view representationTypeName();

#define DEF(T, NAME)                                         \
    template <>                                              \
    constexpr std::string_view representationTypeName<T>() { \
        return NAME;                                         \
    }

DEF(RepresentationType::Latlon, "latlon");
DEF(RepresentationType::RegularGaussian, "regularGaussian");
DEF(RepresentationType::ReducedGaussian, "reducedGaussian");
DEF(RepresentationType::SphericalHarmonics, "sphericalHarmonics");
DEF(RepresentationType::GeneralUnstructured, "generalUnstructured");
DEF(RepresentationType::Healpix, "healpix");
DEF(RepresentationType::Orca, "orca");
DEF(RepresentationType::Fesom, "fesom");
DEF(RepresentationType::Dummy, "dummy");
DEF(RepresentationType::Default, "default");

#undef DEF

}  // namespace metkit::mars2grib::backend::concepts_
