/*
* Copyright (c) 2022 Daniél Kerkmann <daniel@kerkmann.dev>
*
* Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
* the European Commission - subsequent versions of the EUPL (the "Licence");
* You may not use this work except in compliance with the Licence.
* You may obtain a copy of the Licence at:
*
* https://joinup.ec.europa.eu/software/page/eupl
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the Licence is distributed on an "AS IS" basis,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the Licence for the specific language governing permissions and
* limitations under the Licence.
*
* SPDX-License-Identifier: EUPL-1.2
*/

use actix_web::ResponseError;
use dotenv::dotenv;
use serde::Deserialize;
use std::env;
use thiserror::Error;

use crate::types::{Claim, Claims};

#[derive(Error, Debug)]
pub enum ApplicationError {
    #[error("serde url param conversion")]
    SerdeUrlParams(#[from] serde_url_params::Error),
    #[error("serde json conversion")]
    SerdeJson(#[from] serde_json::Error),
    #[error("http client error")]
    HttpClient(#[from] ureq::Error),
    #[error("io error")]
    IO(#[from] std::io::Error),
}

impl ResponseError for ApplicationError {}

#[derive(Debug, Clone, Deserialize)]
pub struct Env {
    pub host: String,
    pub port: u16,
    pub default_claims: Claims,
}

impl Env {
    pub fn init() -> Self {
        dotenv().ok();

        let host = env::var("HOST").unwrap_or_else(|_| "0.0.0.0".to_string());
        let port = env::var("PORT")
            .map(|port| port.parse::<u16>().unwrap())
            .unwrap_or(8080);
        let default_claims = Claims {
            id_token: env::var("DEFAULT_CLAIMS_ID_TOKEN")
                .map(|claim| claim.parse::<Claim>().unwrap())
                .unwrap_or_else(|_| Claim::default()),
            userinfo: env::var("DEFAULT_CLAIMS_USERINFO")
                .map(|claim| claim.parse::<Claim>().unwrap())
                .unwrap_or_else(|_| Claim::default()),
        };

        Env {
            host,
            port,
            default_claims,
        }
    }
}

lazy_static! {
    pub static ref ENV: Env = Env::init();
}
