use sqlx::postgres::{PgPool, PgPoolOptions};
use std::env;
use std::{
    error::Error,
    fs::File,
    io::{BufRead, BufReader},
    path::Path,
};

pub mod article;
pub mod link;

pub async fn establish_connection() -> Result<PgPool, Box<dyn Error>> {
    let db_url = match env::var("ACHUBB_DATABASE_URL") {
        Ok(s) => s,
        Err(_) => panic!("No database environment variable set"),
    };

    let pool = PgPoolOptions::new()
        .max_connections(5)
        .connect(&db_url)
        .await?;

    Ok(pool)
}

pub trait PsqlData {
    async fn read_all(pool: &PgPool) -> Result<Vec<Box<Self>>, Box<dyn Error>>;

    async fn read(pool: &PgPool, id: i32) -> Result<Box<Self>, Box<dyn Error>>;

    async fn insert(&self, pool: &PgPool) -> Result<(), Box<dyn Error>>;

    async fn update(&self, pool: &PgPool) -> Result<(), Box<dyn Error>>;

    async fn delete(&self, pool: &PgPool) -> Result<(), Box<dyn Error>>;
}

//
// The output is wrapped in a Result to allow matching on errors.
// Returns an Iterator to the Reader of the lines of the file.
fn read_lines<P>(filename: P) -> Vec<String>
where
    P: AsRef<Path>,
{
    let file = File::open(filename).unwrap();
    BufReader::new(file).lines().flatten().collect()
}
