use serde::{Deserialize, Serialize};

use crate::model::ProtoMessage;

#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum ProtoScalarKind {
    String,
    Bool,
    Int32,
    Int64,
    Uint32,
    Uint64,
    Float,
    Double,
    Bytes,
}

#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct ProtoEnum {
    pub name: String,
    pub values: Vec<String>,
}

#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct ProtoMapField {
    pub key: ProtoScalarKind,
    pub value: Box<ProtoFieldType>,
}

#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(tag = "kind", rename_all = "snake_case")]
pub enum ProtoFieldType {
    Scalar { scalar: ProtoScalarKind },
    Message { message: Box<ProtoMessage> },
    Enum { enumeration: ProtoEnum },
    Map { map: ProtoMapField },
}

#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum ProtoFieldCardinality {
    Optional,
    Required,
    Repeated,
}

#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct ProtoField {
    pub name: String,
    pub json_name: String,
    pub cardinality: ProtoFieldCardinality,
    pub field_type: ProtoFieldType,
}
