// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

use std::fmt;
use std::str;

use crate::crypto_provider::CryptoProvider;
use fidl_fuchsia_kms::{
    AsymmetricKeyAlgorithm, AsymmetricPrivateKeyRequest, Error, KeyOrigin, KeyProvider,
};
use fidl_fuchsia_mem::Buffer;
use fuchsia_zircon as zx;
use log::error;
use serde::{Deserialize, Serialize};

/// Different type of key request.
pub enum KeyRequestType<'a> {
    /// Request on an asymmetric private key.
    AsymmetricPrivateKeyRequest(AsymmetricPrivateKeyRequest),
    /// Request on a sealing key to seal data.
    SealingKeyRequest(DataRequest<'a>),
    /// Request on a sealing key to unseal data.
    UnsealingKeyRequest(DataRequest<'a>),
}

/// A structure to contain a data buffer as input and a mutable result reference as output.
pub struct DataRequest<'a> {
    pub data: Buffer,
    pub result: &'a mut Result<Buffer, Error>,
}

/// The key types.
#[derive(Serialize, Deserialize, PartialEq, Copy, Clone)]
pub enum KeyType {
    /// A type of key used to seal and unseal data. This type of key is generated by KMS and not the
    /// user.
    SealingKey,
    /// A type of key representing an asymmetric private key. It could be used to sign data.
    AsymmetricPrivateKey,
}

/// A key object in memory.
///
/// Each key stored in KMS should have a singleton of key object in memory when used. The user are
/// given a handler associated with this unique in memory key object. If a key object does not exist
/// KMS would read from storage and create the key object. After all the handles to this key object
/// is dropped, the key object would be removed from memory. This ensures that all the operations
/// are synchronized based on lock to use this Key object.
pub trait KmsKey: Send + fmt::Debug {
    /// Whether this key is already deleted. A key may be deleted while there are other channels
    /// associated with that key. In this case, any operation on the deleted key would return
    /// key_not_found.
    fn is_deleted(&self) -> bool;
    /// Delete the key. This would include telling the crypto provider to delete key (If provider
    /// keeps some resource for the key) and set the deleted to true.
    ///
    /// # Panics
    ///
    /// Panics if the key should never be deleted, for example, the sealing key should never be
    /// deleted.
    fn delete(&mut self) -> Result<(), Error>;
    /// Get the name for the current key.
    fn get_key_name(&self) -> &str;
    /// Handle a request from user. Note that a key should only handle the request for that key
    /// and this is enforced by key_manager. KmsSealingKey is never expected to return a FIDL error
    /// when handling request, for detail, please see KmsSealingKey documentation.
    ///
    /// # Panics
    ///
    /// Panics if request type is invalid.
    fn handle_request(&self, req: KeyRequestType<'_>) -> Result<(), fidl::Error>;
    /// The the type for the current key.
    fn get_key_type(&self) -> KeyType;
    /// Get the crypto provider for the key.
    fn get_key_provider(&self) -> KeyProvider;
    /// Get the key data.
    fn get_key_data(&self) -> Vec<u8>;
}

/// A list of all the supported asymmetric key algorithms.
#[cfg(test)]
pub const ASYMMETRIC_KEY_ALGORITHMS: &[AsymmetricKeyAlgorithm] = &[
    AsymmetricKeyAlgorithm::EcdsaSha256P256,
    AsymmetricKeyAlgorithm::EcdsaSha512P384,
    AsymmetricKeyAlgorithm::EcdsaSha512P521,
    AsymmetricKeyAlgorithm::RsaSsaPssSha2562048,
    AsymmetricKeyAlgorithm::RsaSsaPssSha2563072,
    AsymmetricKeyAlgorithm::RsaSsaPssSha5124096,
    AsymmetricKeyAlgorithm::RsaSsaPkcs1Sha2562048,
    AsymmetricKeyAlgorithm::RsaSsaPkcs1Sha2563072,
    AsymmetricKeyAlgorithm::RsaSsaPkcs1Sha5124096,
];

/// The key attributes structure to be stored as attribute file.
pub struct KeyAttributes<'a> {
    pub asymmetric_key_algorithm: Option<AsymmetricKeyAlgorithm>,
    pub key_type: KeyType,
    pub key_origin: KeyOrigin,
    pub provider: &'a dyn CryptoProvider,
    pub key_data: Vec<u8>,
}

/// Emit a error message and return an error.
///
/// Invoke the `error!` macro on all but the first argument. A call to
/// `debug_err!(err, ...)` is an expression whose value is the expression `err`.
#[macro_export]
macro_rules! debug_err {
    ($err:expr, $($arg:tt)*) => (
        // TODO(joshlf): Uncomment once attributes are allowed on expressions
        // #[cfg_attr(feature = "cargo-clippy", allow(block_in_if_condition_stmt))]
        {
            use ::log::error;
            error!($($arg)*);
            $err
        }
    )
}

/// Create a closure which emits a error message and turn original error to a new error.
///
/// Creates a closure that would return the first argument and print an error message with the
/// original error that is used to call the closure as the last argument to the error message.
macro_rules! debug_err_fn {
    ($return_err:expr, $($arg:tt)*) => (
        |err| {
            use ::log::error;
            error!($($arg)*, err);
            $return_err
        }
    )
}

/// Create a closure which emits a error message and returns an error.
///
/// Creates a closure that takes no argument and return the first argument and print an error
/// message.
macro_rules! debug_err_fn_no_argument {
    ($return_err:expr, $($arg:tt)*) => (
        || {
            use ::log::error;
            error!($($arg)*);
            $return_err
        }
    )
}

#[cfg(test)]
pub fn generate_random_data(size: u32) -> Vec<u8> {
    use rand::Rng;
    let mut random_data = Vec::new();
    let mut rng = rand::thread_rng();
    for _i in 0..size {
        let byte: u8 = rng.gen();
        random_data.push(byte);
    }
    random_data
}

/// Read data from a VMO buffer.
pub fn buffer_to_data(buffer: Buffer) -> Result<Vec<u8>, Error> {
    let buffer_size = buffer.size;
    let buffer_vmo = buffer.vmo;

    let mut input = vec![0; buffer_size as usize];
    buffer_vmo
        .read(&mut input, 0)
        .map_err(debug_err_fn!(Error::InternalError, "Failed to read data from vmo: {:?}."))?;
    Ok(input)
}

/// Write data into a VMO buffer.
pub fn data_to_buffer(data: &[u8]) -> Result<Buffer, Error> {
    let vmo = zx::Vmo::create(data.len() as u64)
        .map_err(debug_err_fn!(Error::InternalError, "Failed to create vmo: {:?}"))?;
    vmo.write(&data, 0)
        .map_err(debug_err_fn!(Error::InternalError, "Failed to write data to vmo: {:?}"))?;
    Ok(Buffer { vmo, size: data.len() as u64 })
}
