
use crate::server::ProducesTickets;
use crate::rand;

use std::mem;
use std::sync::{Mutex, Arc};
use std::time;
use ring::aead;

/// The timebase for expiring and rolling tickets and ticketing
/// keys.  This is UNIX wall time in seconds.
pub fn timebase() -> u64 {
    time::SystemTime::now()
        .duration_since(time::UNIX_EPOCH)
        .unwrap()
        .as_secs()
}

/// This is a `ProducesTickets` implementation which uses
/// any *ring* `aead::Algorithm` to encrypt and authentication
/// the ticket payload.  It does not enforce any lifetime
/// constraint.
pub struct AEADTicketer {
    alg: &'static aead::Algorithm,
    key: aead::LessSafeKey,
    lifetime: u32,
}

impl AEADTicketer {
    /// Make a new `AEADTicketer` using the given `alg`, `key` material
    /// and advertised `lifetime_seconds`.  Note that `lifetime_seconds`
    /// does not affect the lifetime of the key.  `key` must be the
    /// right length for `alg` or this will panic.
    pub fn new_custom(alg: &'static aead::Algorithm,
                      key: &[u8],
                      lifetime_seconds: u32)
                      -> AEADTicketer {
        let key = aead::UnboundKey::new(alg, key)
            .unwrap();
        AEADTicketer {
            alg,
            key: aead::LessSafeKey::new(key),
            lifetime: lifetime_seconds,
        }
    }

    /// Make a ticketer with recommended configuration and a random key.
    pub fn new() -> AEADTicketer {
        let mut key = [0u8; 32];
        rand::fill_random(&mut key);
        AEADTicketer::new_custom(&aead::CHACHA20_POLY1305, &key, 60 * 60 * 12)
    }
}

impl ProducesTickets for AEADTicketer {
    fn enabled(&self) -> bool {
        true
    }
    fn get_lifetime(&self) -> u32 {
        self.lifetime
    }

    /// Encrypt `message` and return the ciphertext.
    fn encrypt(&self, message: &[u8]) -> Option<Vec<u8>> {
        // Random nonce, because a counter is a privacy leak.
        let mut nonce_buf = [0u8; 12];
        rand::fill_random(&mut nonce_buf);
        let nonce = ring::aead::Nonce::assume_unique_for_key(nonce_buf);
        let aad = ring::aead::Aad::empty();

        let mut ciphertext =
            Vec::with_capacity(nonce_buf.len() + message.len() + self.key.algorithm().tag_len());
        ciphertext.extend(&nonce_buf);
        ciphertext.extend(message);
        self.key.seal_in_place_separate_tag(nonce,aad, &mut ciphertext[nonce_buf.len()..])
            .map(|tag| {
                ciphertext.extend(tag.as_ref());
                ciphertext
            })
            .ok()
    }

    /// Decrypt `ciphertext` and recover the original message.
    fn decrypt(&self, ciphertext: &[u8]) -> Option<Vec<u8>> {
        let nonce_len = self.alg.nonce_len();
        let tag_len = self.alg.tag_len();

        if ciphertext.len() < nonce_len + tag_len {
            return None;
        }

        let nonce = ring::aead::Nonce::try_assume_unique_for_key(&ciphertext[0..nonce_len]).unwrap();
        let aad = ring::aead::Aad::empty();

        let mut out = Vec::new();
        out.extend_from_slice(&ciphertext[nonce_len..]);

        let plain_len = match self.key.open_in_place(nonce, aad, &mut out) {
            Ok(plaintext) => plaintext.len(),
            Err(..) => { return None; }
        };

        out.truncate(plain_len);
        Some(out)
    }
}

struct TicketSwitcherState {
    current: Box<dyn ProducesTickets>,
    previous: Option<Box<dyn ProducesTickets>>,
    next_switch_time: u64,
}

/// A ticketer that has a 'current' sub-ticketer and a single
/// 'previous' ticketer.  It creates a new ticketer every so
/// often, demoting the current ticketer.
pub struct TicketSwitcher {
    generator: fn() -> Box<dyn ProducesTickets>,
    lifetime: u32,
    state: Mutex<TicketSwitcherState>,
}

impl TicketSwitcher {
    /// `lifetime` is in seconds, and is how long the current ticketer
    /// is used to generate new tickets.  Tickets are accepted for no
    /// longer than twice this duration.  `generator` produces a new
    /// `ProducesTickets` implementation.
    pub fn new(lifetime: u32,
               generator: fn() -> Box<dyn ProducesTickets>)
               -> TicketSwitcher {
        TicketSwitcher {
            generator,
            lifetime,
            state: Mutex::new(TicketSwitcherState {
                current: generator(),
                previous: None,
                next_switch_time: timebase() + u64::from(lifetime),
            }),
        }
    }

    /// If it's time, demote the `current` ticketer to `previous` (so it
    /// does no new encryptions but can do decryptions) and make a fresh
    /// `current` ticketer.
    ///
    /// Calling this regularly will ensure timely key erasure.  Otherwise,
    /// key erasure will be delayed until the next encrypt/decrypt call.
    pub fn maybe_roll(&self) {
        let mut state = self.state.lock().unwrap();
        let now = timebase();

        if now > state.next_switch_time {
            state.previous = Some(mem::replace(&mut state.current, (self.generator)()));
            state.next_switch_time = now + u64::from(self.lifetime);
        }
    }
}

impl ProducesTickets for TicketSwitcher {
    fn get_lifetime(&self) -> u32 {
        self.lifetime * 2
    }

    fn enabled(&self) -> bool {
        true
    }

    fn encrypt(&self, message: &[u8]) -> Option<Vec<u8>> {
        self.maybe_roll();

        self.state
            .lock()
            .unwrap()
            .current
            .encrypt(message)
    }

    fn decrypt(&self, ciphertext: &[u8]) -> Option<Vec<u8>> {
        self.maybe_roll();

        let state = self.state.lock().unwrap();
        let rc = state.current.decrypt(ciphertext);

        if rc.is_none() && state.previous.is_some() {
            state.previous.as_ref().unwrap().decrypt(ciphertext)
        } else {
            rc
        }
    }
}

/// A concrete, safe ticket creation mechanism.
pub struct Ticketer {}

fn generate_inner() -> Box<dyn ProducesTickets> {
    Box::new(AEADTicketer::new())
}

impl Ticketer {
    /// Make the recommended Ticketer.  This produces tickets
    /// with a 12 hour life and randomly generated keys.
    ///
    /// The encryption mechanism used in Chacha20Poly1305.
    pub fn new() -> Arc<dyn ProducesTickets> {
        Arc::new(TicketSwitcher::new(6 * 60 * 60, generate_inner))
    }
}

#[test]
fn basic_pairwise_test() {
    let t = Ticketer::new();
    assert_eq!(true, t.enabled());
    let cipher = t.encrypt(b"hello world")
        .unwrap();
    let plain = t.decrypt(&cipher)
        .unwrap();
    assert_eq!(plain, b"hello world");
}
