#[macro_use]
extern crate lazy_static;
#[macro_use]
extern crate serde_derive;
#[macro_use]
extern crate diesel;
#[macro_use]
extern crate diesel_migrations;

use actix_files::Files;
use actix_web::client::Client;
use actix_web::{web, App, HttpRequest, FromRequest, HttpServer};
use diesel::prelude::*;
use diesel::r2d2::{self, ConnectionManager};
use url::Url;

use crate::config::CONFIG;
use crate::config::PAYLOAD_LIMIT;
use crate::forward::*;

mod account;
mod config;
mod database;
mod errors;
mod forward;
mod sniff;
mod templates;

// default to postgres
#[cfg(feature = "default")]
type DbConn = PgConnection;
#[cfg(feature = "default")]
embed_migrations!("migrations/postgres");

#[cfg(feature = "postgres")]
type DbConn = PgConnection;
#[cfg(feature = "postgres")]
embed_migrations!("migrations/postgres");

#[cfg(feature = "sqlite")]
type DbConn = SqliteConnection;
#[cfg(feature = "sqlite")]
embed_migrations!("migrations/sqlite");

#[cfg(feature = "mysql")]
type DbConn = MysqlConnection;
#[cfg(feature = "mysql")]
embed_migrations!("migrations/mysql");

type DbPool = r2d2::Pool<ConnectionManager<DbConn>>;

#[actix_rt::main]
async fn main() -> std::io::Result<()> {
    /*    std::env::set_var("RUST_LOG", "actix_web=debug");
    env_logger::init();*/

    println!("ta ta tala ~ SNCF init");

    println!("Checking configuration file...");
    CONFIG.check_version();

    if CONFIG.database_path.len() == 0 {
        println!("No database specified. Please enter a MySQL, PostgreSQL or SQLite connection string in config.toml.");
    }

    debug(&format!("Opening database {}", CONFIG.database_path));

    let manager = ConnectionManager::<DbConn>::new(&CONFIG.database_path);
    let pool = r2d2::Pool::builder()
        .build(manager)
        .expect("ERROR: main: Failed to create the database pool.");

    let conn = pool.get().expect("ERROR: main: DB connection failed");

    println!("Running migrations...");
    embedded_migrations::run(&*conn).expect("ERROR: main: Failed to run database migrations");

    let forward_url =
        Url::parse(&CONFIG.nextcloud_url).expect("Couldn't parse the forward url from config");

    println!(
        "Now listening at {}:{}",
        CONFIG.listening_address, CONFIG.listening_port
    );
    
    
    
    // starting the http server
    let HttpServer::new(move || {
        App::new()
            .data(pool.clone())
            .data(Client::new())
            .data(forward_url.clone())
            /*.route("/mimolette", web::get().to(login))*/
            /*.route("/login", web::post().to(forward))*/
            /*.wrap(middleware::Compress::default())*/
            .service(Files::new("/assets/", "./templates/assets/").index_file("index.html"))
            .route("/", web::get().to(index))
            .route("/link", web::post().to(forward_register))
            .route("/admin/{token}", web::get().to(forward_login))
            .default_service(web::route().to(forward))
            .data(String::configure(|cfg| cfg.limit(PAYLOAD_LIMIT)))
            .app_data(actix_web::web::Bytes::configure(|cfg| {
                cfg.limit(PAYLOAD_LIMIT)
            }))
    })
    .bind((CONFIG.listening_address.as_str(), CONFIG.listening_port))?
    .system_exit()
    .run()
    .await
}

pub fn debug(text: &str) {
    if CONFIG.debug_mode {
        println!("{}", text);
    }
}

