use tokio_postgres::Row;

use petro::entity::Entity;
use petro::entity::EntityColumn;
use petro::entity::EntityId;
use petro::entity::EntityMetadata;
use petro::query::QueryBindings;

#[derive(Debug, Clone)]
pub struct Customer {
    pub id: EntityId<Customer>,
    pub name: String,
}

pub struct CustomerColumns {
    pub id: &'static EntityColumn<EntityId<Customer>>,
    pub name: &'static EntityColumn<String>,
}

impl Customer {
    const C: &'static CustomerColumns = &CustomerColumns {
        id: &EntityColumn::new("id"),
        name: &EntityColumn::new("name"),
    };
}

impl EntityMetadata for Customer {
    const TABLE_NAME: &'static str = "customer";

    type Columns = CustomerColumns;
    const C: &'static Self::Columns = Customer::C;
    const COLUMN_NAMES: &'static [&'static str] = &["id", "name"];
}

impl Entity for Customer {
    const ID_COLUMN_INDEX: usize = 0;

    type EntityIdType = Self;
    fn id(&self) -> &EntityId<Self> {
        return &self.id;
    }

    fn from_db_row(row: &Row, offset: usize) -> Self {
        return Self {
            id: row.get(offset + 0),
            name: row.get(offset + 1),
        };
    }

    fn bind_db_params<'a>(&'a self, params: &mut QueryBindings<'a>) {
        params.add(&self.id);
        params.add(&self.name);
    }
}
