//! Common definitions for the feature-check test generator.

use std::collections::HashMap;

use serde::{Deserialize, Serialize};

quick_error! {
    /// An error that occurred during the test file generation.
    #[derive(Debug)]
    pub enum FTestError {
        /// Functionality that is yet to be implemented.
        NotImplemented(msg: String) { display("Not implemented: {}", msg) }
    }
}

/// Runtime configuration for the feature-check test generator.
#[derive(Debug)]
pub struct Config {
    /// The path to the JSON test data file.
    pub data_path: String,
    /// The path to the output file to generate.
    pub output_path: String,
    /// The path to the Handlebars template to use.
    pub template_path: String,
    /// Verbose operation (diagnostic output).
    pub verbose: bool,
}

impl config_diag::ConfigDiag for Config {
    fn diag_is_verbose(&self) -> bool {
        self.verbose
    }
}

/// The version of a test data's format specification.
#[derive(Debug, Deserialize, Serialize)]
pub struct TestFormatVersion {
    /// The version major number.
    pub major: u32,
    /// The version minor number.
    pub minor: u32,
}

/// Metadata about a test data file's format.
#[derive(Debug, Deserialize, Serialize)]
pub struct TestFormat {
    /// The version of the test format specification.
    pub version: TestFormatVersion,
}

/// A synonym for a comparison operator.
#[derive(Debug, Deserialize, Serialize)]
pub struct TestOpSynonym {
    /// The word name of the comparison operator.
    pub name: String,
    /// The symbol to use for the comparison operator.
    pub sym: String,
}

/// Test data for a single simple expression check.
#[derive(Debug, Deserialize, Serialize)]
pub struct TestSimpleCompare {
    /// The feature to compare against ("base" or "beta").
    pub name: String,
    /// The comparison operator.
    pub op: String,
    /// The version to compare against.
    pub version: String,
    /// The comparison result.
    pub result: bool,
}

/// Test data for simple expression checks.
#[derive(Debug, Deserialize, Serialize)]
pub struct SimpleTestData {
    /// The base version to compare against.
    pub features: HashMap<String, String>,
    /// The synonyms to define for the comparison operators.
    pub synonyms: Vec<TestOpSynonym>,
    /// The versions to compare against.
    pub compare: Vec<TestSimpleCompare>,
}

/// Test data parsed out of an input file.
#[derive(Debug, Deserialize, Serialize)]
pub struct TestData {
    /// The input file's metadata format info.
    pub format: TestFormat,
    /// The simple expression tests to run.
    pub simple: SimpleTestData,
}

/// The name of the template to use within the Handlebars renderer.
pub const TEMPLATE_NAME: &str = "test";
