// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

use anyhow::anyhow;
use anyhow::bail;
use anyhow::Result;
use http::Uri;
use std::fs;
use std::io::Write;
use std::path::PathBuf;
use std::sync::Arc;
use structopt::StructOpt;
use teaclave_attestation::report::AttestationReport;

use teaclave_crypto::{AesGcm128Key, AesGcm256Key, TeaclaveFile128Key};

const FILE_AUTH_TAG_LENGTH: usize = 16;
type CMac = [u8; FILE_AUTH_TAG_LENGTH];
type KeyVec = Vec<u8>; // Need define a type to use parse derive macro

fn decode_hex(src: &str) -> Result<Vec<u8>, hex::FromHexError> {
    hex::decode(src)
}

#[derive(Debug, StructOpt)]
struct EncryptDecryptOpt {
    /// Crypto algorithm, supported algorithms are "aes-gcm-128", "aes-gcm-256",
    /// "teaclave-file-128".
    #[structopt(short, long)]
    algorithm: String,

    /// Key in the hex format.
    #[structopt(short, long, parse(try_from_str = decode_hex))]
    key: KeyVec,

    /// IV for AES keys in the hex format.
    #[structopt(long, parse(try_from_str = decode_hex))]
    iv: Option<KeyVec>,

    /// Path of input file.
    #[structopt(short, long = "input-file")]
    input_file: PathBuf,

    /// Path of output file.
    #[structopt(short, long = "output-file")]
    output_file: PathBuf,

    /// Flag to print out CMAC.
    #[structopt(short = "c", long = "print-cmac")]
    print_cmac: bool,
}

#[derive(Debug, StructOpt)]
struct VerifyOpt {
    /// Path of enclave info
    #[structopt(short, long = "enclave-info")]
    enclave_info: PathBuf,

    /// Path of signatures
    #[structopt(required = true, short, long)]
    signatures: Vec<PathBuf>,

    /// Path of auditor's public key
    #[structopt(required = true, short, long = "public-keys")]
    public_keys: Vec<PathBuf>,
}

#[derive(Debug, StructOpt)]
struct AttestOpt {
    /// Address of the remote service
    #[structopt(short, long)]
    address: String,

    /// CA cert of attestation service for verifying the attestation report
    #[structopt(short = "c", long)]
    as_ca_cert: PathBuf,
}

#[derive(Debug, StructOpt)]
enum Command {
    /// Encrypt file
    #[structopt(name = "encrypt")]
    Encrypt(EncryptDecryptOpt),

    /// Decrypt file
    #[structopt(name = "decrypt")]
    Decrypt(EncryptDecryptOpt),

    /// Verify signatures of enclave info with auditors' public keys
    #[structopt(name = "verify")]
    Verify(VerifyOpt),

    /// Display the attestation report of remote Teaclave services
    #[structopt(name = "attest")]
    Attest(AttestOpt),
}

#[derive(Debug, StructOpt)]
#[structopt(name = "teaclave_cli", about = "Teaclave command line tool.")]
struct Opt {
    #[structopt(subcommand)]
    command: Command,
}

fn decrypt(opt: EncryptDecryptOpt) -> Result<CMac> {
    let key = opt.key;
    let mut cmac: CMac = [0u8; FILE_AUTH_TAG_LENGTH];
    match opt.algorithm.as_str() {
        AesGcm128Key::SCHEMA => {
            let iv = opt.iv.expect("IV is required.");
            let key = AesGcm128Key::new(&key, &iv)?;
            let mut content = fs::read(opt.input_file)?;
            let res = key.decrypt(&mut content)?;
            cmac.copy_from_slice(&res);
            fs::write(opt.output_file, content)?;
        }
        AesGcm256Key::SCHEMA => {
            let iv = opt.iv.expect("IV is required.");
            let key = AesGcm256Key::new(&key, &iv)?;
            let mut content = fs::read(opt.input_file)?;
            let res = key.decrypt(&mut content)?;
            cmac.copy_from_slice(&res);
            fs::write(opt.output_file, content)?;
        }
        TeaclaveFile128Key::SCHEMA => {
            let key = TeaclaveFile128Key::new(&key)?;
            let mut output_file = fs::File::create(opt.output_file)?;
            let res = key.decrypt(opt.input_file, &mut output_file)?;
            cmac.copy_from_slice(&res);
        }
        _ => bail!("Invalid crypto algorithm"),
    }

    Ok(cmac)
}

fn encrypt(opt: EncryptDecryptOpt) -> Result<CMac> {
    let key = opt.key;
    let mut cmac: CMac = [0u8; FILE_AUTH_TAG_LENGTH];
    match opt.algorithm.as_str() {
        AesGcm128Key::SCHEMA => {
            let iv = opt.iv.expect("IV is required.");
            let key = AesGcm128Key::new(&key, &iv)?;
            let mut content = fs::read(opt.input_file)?;
            let res = key.encrypt(&mut content)?;
            cmac.copy_from_slice(&res);
            fs::write(opt.output_file, content)?;
        }
        AesGcm256Key::SCHEMA => {
            let iv = opt.iv.expect("IV is required.");
            let key = AesGcm256Key::new(&key, &iv)?;
            let mut content = fs::read(opt.input_file)?;
            let res = key.encrypt(&mut content)?;
            cmac.copy_from_slice(&res);
            fs::write(opt.output_file, content)?;
        }
        TeaclaveFile128Key::SCHEMA => {
            let key = TeaclaveFile128Key::new(&key)?;
            let content = fs::File::open(opt.input_file)?;
            let res = key.encrypt(opt.output_file, content)?;
            cmac.copy_from_slice(&res);
        }
        _ => bail!("Invalid crypto algorithm"),
    }

    Ok(cmac)
}

fn verify(opt: VerifyOpt) -> Result<bool> {
    let enclave_info = fs::read(opt.enclave_info)?;
    let mut public_keys = Vec::new();
    let mut signatures = Vec::new();
    for p in opt.public_keys {
        let content = fs::read(p)?;
        let pem = pem::parse(content).expect("Expect a valid PEM file");
        public_keys.push(pem.contents);
    }

    for s in opt.signatures {
        signatures.push(fs::read(s)?);
    }

    Ok(teaclave_types::EnclaveInfo::verify(
        &enclave_info,
        &public_keys,
        &signatures,
    ))
}

struct TeaclaveServerCertVerifier {
    pub root_ca: Vec<u8>,
}

impl TeaclaveServerCertVerifier {
    pub fn new(root_ca: &[u8]) -> Self {
        Self {
            root_ca: root_ca.to_vec(),
        }
    }

    fn display_attestation_report(&self, cert_der: &[u8]) -> bool {
        match AttestationReport::from_cert(&cert_der, &self.root_ca) {
            Ok(report) => println!("{}", report),
            Err(e) => println!("{:?}", e),
        }
        true
    }
}

impl rustls::ServerCertVerifier for TeaclaveServerCertVerifier {
    fn verify_server_cert(
        &self,
        _roots: &rustls::RootCertStore,
        certs: &[rustls::Certificate],
        _hostname: webpki::DNSNameRef,
        _ocsp: &[u8],
    ) -> std::result::Result<rustls::ServerCertVerified, rustls::TLSError> {
        // This call automatically verifies certificate signature
        if certs.len() != 1 {
            return Err(rustls::TLSError::NoCertificatesPresented);
        }
        if self.display_attestation_report(&certs[0].0) {
            Ok(rustls::ServerCertVerified::assertion())
        } else {
            Err(rustls::TLSError::WebPKIError(
                webpki::Error::ExtensionValueInvalid,
            ))
        }
    }
}

fn attest(opt: AttestOpt) -> Result<()> {
    let uri = opt.address.parse::<Uri>()?;
    let hostname = uri.host().ok_or_else(|| anyhow!("Invalid hostname."))?;
    let mut stream = std::net::TcpStream::connect(opt.address)?;
    let hostname = webpki::DNSNameRef::try_from_ascii_str(hostname)?;
    let content = fs::read(opt.as_ca_cert)?;
    let pem = pem::parse(content)?;
    let verifier = Arc::new(TeaclaveServerCertVerifier::new(&pem.contents));
    let mut config = rustls::ClientConfig::new();
    config.dangerous().set_certificate_verifier(verifier);
    config.versions.clear();
    config.enable_sni = false;
    config.versions.push(rustls::ProtocolVersion::TLSv1_2);
    let rc_config = Arc::new(config);

    let mut session = rustls::ClientSession::new(&rc_config, hostname);
    let mut tls_stream = rustls::Stream::new(&mut session, &mut stream);
    tls_stream.write_all(&[0]).unwrap();

    Ok(())
}

fn main() -> Result<()> {
    env_logger::init();
    let args = Opt::from_args();
    match args.command {
        Command::Decrypt(opt) => {
            let flag = opt.print_cmac;
            let cmac = decrypt(opt)?;
            if flag {
                let cmac_string = hex::encode(cmac);
                println!("{}", cmac_string);
            }
        }
        Command::Encrypt(opt) => {
            let flag = opt.print_cmac;
            let cmac = encrypt(opt)?;
            if flag {
                let cmac_string = hex::encode(cmac);
                println!("{}", cmac_string);
            }
        }
        Command::Verify(opt) => match verify(opt) {
            Ok(false) | Err(_) => bail!("Failed to verify signatures."),
            Ok(true) => {
                println!("Verify successfully.");
                return Ok(());
            }
        },
        Command::Attest(opt) => attest(opt)?,
    };

    Ok(())
}
