// Copyright 2018 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 crate::{AuthDbError, CredentialValue};

use anyhow::{format_err, Error};
use log::warn;
use serde::Serialize;
use serde_json::Value;
use std::io::{Read, Write};
use std::result;

pub type Result<T> = result::Result<T, AuthDbError>;

/// The character set used for all base64 encoding
const CHARSET: base64::Config = base64::STANDARD_NO_PAD;

/// A trait defining the ability to convert CredentialValues to bytes and back.
///
/// Currently we supply a single implementation of this trait using serde_json,
/// but in the future we may want to transition to some binary format such as
/// FIDL tables.
pub trait Serializer {
    /// Outputs a serialized form of credentials into writer.
    fn serialize<'a, W, I>(&self, writer: W, credentials: I) -> Result<()>
    where
        W: Write,
        I: Iterator<Item = &'a CredentialValue>;

    /// Deserializes data from reader to return a vector of credentials. Any
    /// malformed credentials in the input data will be logged and discarded.
    /// If all the credentials in a file are malformed the method returns an
    /// error.
    fn deserialize<R: Read>(&self, reader: R) -> Result<Vec<CredentialValue>>;
}

#[derive(Serialize)]
struct StoredCredentialValue<'a> {
    auth_provider_type: &'a str,
    user_profile_id: String,
    refresh_token: String,
    #[serde(skip_serializing_if = "Option::is_none")]
    private_key: Option<String>,
}

// Note: We provide a custom Serde serialization for CredentialValue so we can
// choose the specific fields that we wish to base64 encode, and to reduce the
// risk of inconsistencies with the manual deserialization.
impl serde::ser::Serialize for CredentialValue {
    fn serialize<S>(&self, serializer: S) -> result::Result<S::Ok, S::Error>
    where
        S: serde::ser::Serializer,
    {
        StoredCredentialValue {
            auth_provider_type: &self.credential_key.auth_provider_type,
            user_profile_id: base64::encode_config(&self.credential_key.user_profile_id, CHARSET),
            refresh_token: base64::encode_config(&self.refresh_token, CHARSET),
            private_key: self.private_key.as_ref().map(|key| base64::encode_config(key, CHARSET)),
        }
        .serialize(serializer)
    }
}

/// A Serializer that uses JSON formatting with the help of serde_json
pub struct JsonSerializer;

impl JsonSerializer {
    /// Constructs a new CredentialValue from the supplied json object.
    fn build_credential_value(json: &Value) -> result::Result<CredentialValue, Error> {
        CredentialValue::new(
            entry_to_str(&json, "auth_provider_type")?.to_string(),
            base64_entry_to_str(&json, "user_profile_id")?,
            base64_entry_to_str(&json, "refresh_token")?,
            match &json.get("private_key") {
                Some(Value::String(_)) => Some(base64_entry_to_bytes(&json, "private_key")?),
                _ => None,
            },
        )
    }
}

impl Serializer for JsonSerializer {
    fn serialize<'a, W, I>(&self, writer: W, credentials: I) -> Result<()>
    where
        W: Write,
        I: Iterator<Item = &'a CredentialValue>,
    {
        let credential_vec: Vec<&CredentialValue> = credentials.collect();
        serde_json::to_writer(writer, &credential_vec).map_err(|err| {
            warn!("Credential serialization error: {:?}", err);
            AuthDbError::SerializationError
        })
    }

    fn deserialize<R: Read>(&self, reader: R) -> Result<Vec<CredentialValue>> {
        // Manually parse the json tree so that we can be more tolerant of partially
        // invalid data and support changes in the credential definition over time.
        match serde_json::from_reader(reader) {
            Ok(Value::Array(json_creds)) => {
                let creds: Vec<CredentialValue> = json_creds
                    .iter()
                    .filter_map(|c| {
                        Self::build_credential_value(c)
                            .map_err(|err| warn!("Error parsing credential {:?}", err))
                            .ok()
                    })
                    .collect();
                // Return an error if the file contained credentials but *none* were valid.
                if creds.is_empty() && !json_creds.is_empty() {
                    Err(AuthDbError::DbInvalid)
                } else {
                    Ok(creds)
                }
            }
            Ok(_) => {
                warn!("Credential JSON root element is not an array");
                Err(AuthDbError::SerializationError)
            }
            Err(err) => {
                warn!("Credential deserialization error: {:?}", err);
                Err(AuthDbError::SerializationError)
            }
        }
    }
}

/// Returns a string field from the supplied json object, or a descriptive error if this is not
/// possible.
fn entry_to_str<'a>(object: &'a Value, field_name: &'static str) -> result::Result<&'a str, Error> {
    match object.get(field_name) {
        Some(Value::String(s)) => Ok(s),
        _ => Err(format_err!("Invalid credential: {} not found", field_name)),
    }
}

/// Returns the base64 decoded contents of a string field from the supplied json object, or a
/// descriptive error if this is not possible.
fn base64_entry_to_bytes(
    object: &Value,
    field_name: &'static str,
) -> result::Result<Vec<u8>, Error> {
    let encoded_string = entry_to_str(object, field_name)?;
    base64::decode_config(encoded_string, CHARSET)
        .map_err(|_| format_err!("Invalid credential: {} invalid base64", field_name))
}

/// Returns the base64 decoded contents of a string field from the supplied json object, or a
/// descriptive error if this is not possible.
fn base64_entry_to_str(object: &Value, field_name: &'static str) -> result::Result<String, Error> {
    let decoded_bytes = base64_entry_to_bytes(object, field_name)?;
    String::from_utf8(decoded_bytes)
        .map_err(|_| format_err!("Invalid credential: {} invalid UTF-8", field_name))
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::CredentialKey;
    use std::io::Cursor;
    use std::str;

    fn build_test_creds(suffix: &str) -> CredentialValue {
        CredentialValue {
            credential_key: CredentialKey {
                auth_provider_type: "test".to_string(),
                user_profile_id: "id".to_string() + suffix,
            },
            refresh_token: "ref".to_string() + suffix,
            private_key: None,
        }
    }

    #[test]
    fn test_json_serialize_deserialize_zero_items() -> Result<()> {
        let input = vec![];

        let mut serialized = Vec::<u8>::new();
        JsonSerializer.serialize(&mut serialized, input.iter())?;
        assert_eq!(str::from_utf8(&serialized).unwrap(), "[]");

        let deserialized = JsonSerializer.deserialize(Cursor::new(serialized))?;
        assert_eq!(deserialized, input);
        Ok(())
    }

    #[test]
    fn test_json_serialize_deserialize_one_item() -> Result<()> {
        let input = vec![build_test_creds("1")];

        let mut serialized = Vec::<u8>::new();
        JsonSerializer.serialize(&mut serialized, input.iter())?;
        assert_eq!(
            str::from_utf8(&serialized).unwrap(),
            "[{\"auth_provider_type\":\"test\",\"user_profile_id\":\"aWQx\",\"refresh_token\":\
             \"cmVmMQ\"}]"
        );

        let deserialized = JsonSerializer.deserialize(Cursor::new(serialized))?;
        assert_eq!(deserialized, input);
        Ok(())
    }

    #[test]
    fn test_json_serialize_deserialize_multiple_items() -> Result<()> {
        let mut input = vec![build_test_creds("1"), build_test_creds("2"), build_test_creds("3")];
        // Include a mix of bound and unbound test credentials.
        input[1].private_key = Some(vec![7, 6, 5, 4, 3, 2, 1]);

        let mut serialized = Vec::<u8>::new();
        JsonSerializer.serialize(&mut serialized, input.iter())?;

        let deserialized = JsonSerializer.deserialize(Cursor::new(serialized))?;
        assert_eq!(deserialized, input);
        Ok(())
    }

    #[test]
    fn test_json_deserialize_bad_root() {
        let content = "{\"auth_provider_type\":\"test\",\"user_profile_id\":\"aWQx\",\
                       \"refresh_token\":\"cmVmMQ\"}";
        let deserialized = JsonSerializer.deserialize(content.as_bytes());
        assert_match!(deserialized, Err(AuthDbError::SerializationError));
    }

    #[test]
    fn test_json_deserialize_missing_field() {
        let content = "[{\"auth_provider_type\":\"test\",\"refresh_token\":\"cmVmMQ\"}]";
        let deserialized = JsonSerializer.deserialize(content.as_bytes());
        match deserialized {
            Err(AuthDbError::DbInvalid) => {}
            _ => panic!(),
        }
        assert_match!(deserialized, Err(AuthDbError::DbInvalid));
    }

    #[test]
    fn test_json_deserialize_invalid_base64() {
        let content = "[{\"auth_provider_type\":\"test\",\"user_profile_id\":\"a$$x\",\
                       \"refresh_token\":\"cmVmMQ\"}]";
        let deserialized = JsonSerializer.deserialize(content.as_bytes());
        assert_match!(deserialized, Err(AuthDbError::DbInvalid));
    }
}
