use actix_web::{App, http, HttpServer, web::Data};
use actix_cors::Cors;
use actix_governor::{Governor, GovernorConfigBuilder};
use dotenvy::dotenv;

use sqlx::mysql::{MySqlPool, MySqlPoolOptions};
use std::env;

mod api;
use api::{sample};

#[derive(Clone, Debug)]
pub struct AppState {
    pool: MySqlPool,
}

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    dotenv().ok();
    let db_connection = env::var("DATABASE_URL").unwrap();
    let pool: MySqlPool = MySqlPoolOptions::new()
        .connect(db_connection.as_str())
        .await
        .unwrap();
    let app_state = AppState { pool };

    HttpServer::new(move || {
      let cors = Cors::default()
        .allowed_origin("localhost:4321")
        .allowed_methods(vec!["GET", "POST"])
        .allowed_headers(vec![http::header::AUTHORIZATION, http::header::ACCEPT])
        .allowed_header(http::header::CONTENT_TYPE)
        .max_age(3600);

      let governor_conf = GovernorConfigBuilder::default()
        .seconds_per_request(2)
        .burst_size(20)
        .finish()
        .unwrap();

      App::new()
          .app_data(Data::new(app_state.pool.clone()))
          .wrap(cors)
          .wrap(Governor::new(&governor_conf))
          .service(sample)
    })
    .bind(("127.0.0.1", 4320))?
    .run()
    .await
}
