// 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.

//! A Fuchsia Driver Bind Program compiler

use anyhow::{anyhow, Context, Error};
use bind_debugger::instruction::{Condition, Instruction, InstructionInfo};
use bind_debugger::test;
use bind_debugger::{bind_library, compiler, offline_debugger};
use std::convert::TryFrom;
use std::fmt::Write;
use std::fs::File;
use std::io::prelude::*;
use std::io::{self, BufRead, Write as IoWrite};
use std::path::PathBuf;
use structopt::StructOpt;

const AUTOBIND_PROPERTY: u32 = 0x0002;

#[derive(StructOpt, Debug)]
struct SharedOptions {
    /// The bind library input files. These may be included by the bind program. They should be in
    /// the format described in //tools/bindc/README.md.
    #[structopt(short = "i", long = "include", parse(from_os_str))]
    include: Vec<PathBuf>,

    /// Specifiy the bind library input files as a file. The file must contain a list of filenames
    /// that are bind library input files that may be included by the bind program. Those files
    /// should be in the format described in //tools/bindc/README.md.
    #[structopt(short = "f", long = "include-file", parse(from_os_str))]
    include_file: Option<PathBuf>,

    /// The bind program input file. This should be in the format described in
    /// //tools/bindc/README.md. This is required unless disable_autobind is true, in which case
    /// the driver while bind unconditionally (but only on the user's request.)
    #[structopt(parse(from_os_str))]
    input: Option<PathBuf>,
}

#[derive(StructOpt, Debug)]
enum Command {
    #[structopt(name = "compile")]
    Compile {
        #[structopt(flatten)]
        options: SharedOptions,

        /// Output file. The compiler emits a C header file.
        #[structopt(short = "o", long = "output", parse(from_os_str))]
        output: Option<PathBuf>,

        /// Specify a path for the compiler to generate a depfile. A depfile contain, in Makefile
        /// format, the files that this invocation of the compiler depends on including all bind
        /// libraries and the bind program input itself. An output file must be provided to generate
        /// a depfile.
        #[structopt(short = "d", long = "depfile", parse(from_os_str))]
        depfile: Option<PathBuf>,

        // TODO(fxbug.dev/43400): Eventually this option should be removed when we can define this
        // configuration in the driver's component manifest.
        /// Disable automatically binding the driver so that the driver must be bound on a user's
        /// request.
        #[structopt(short = "a", long = "disable-autobind")]
        disable_autobind: bool,

        /// Output a bytecode file, instead of a C header file.
        #[structopt(short = "b", long = "output-bytecode")]
        output_bytecode: bool,
    },
    #[structopt(name = "debug")]
    Debug {
        #[structopt(flatten)]
        options: SharedOptions,

        /// A file containing the properties of a specific device, as a list of key-value pairs.
        /// This will be used as the input to the bind program debugger.
        #[structopt(short = "d", long = "debug", parse(from_os_str))]
        device_file: PathBuf,
    },
    #[structopt(name = "test")]
    Test {
        #[structopt(flatten)]
        options: SharedOptions,

        // TODO(fxbug.dev/56774): Refer to documentation for bind testing.
        /// A file containing the test specification.
        #[structopt(short = "t", long = "test-spec", parse(from_os_str))]
        test_spec: PathBuf,
    },
    #[structopt(name = "generate")]
    Generate {
        #[structopt(flatten)]
        options: SharedOptions,

        /// Output FIDL file.
        #[structopt(short = "o", long = "output", parse(from_os_str))]
        output: Option<PathBuf>,
    },
}

fn main() {
    let command = Command::from_iter(std::env::args());
    if let Err(err) = handle_command(command) {
        eprintln!("{}", err);
        std::process::exit(1);
    }
}

fn write_depfile(
    output: &PathBuf,
    input: &Option<PathBuf>,
    includes: &[PathBuf],
) -> Result<String, Error> {
    fn path_to_str(path: &PathBuf) -> Result<&str, Error> {
        path.as_os_str().to_str().context("failed to convert path to string")
    };

    let mut deps = includes.iter().map(|s| path_to_str(s)).collect::<Result<Vec<&str>, Error>>()?;

    if let Some(input) = input {
        let input_str = path_to_str(input)?;
        deps.push(input_str);
    }

    let output_str = path_to_str(output)?;
    let mut out = String::new();
    writeln!(&mut out, "{}: {}", output_str, deps.join(" "))?;
    Ok(out)
}

fn write_bind_bytecode(instructions: Vec<InstructionInfo>) -> Vec<u8> {
    instructions
        .into_iter()
        .map(|inst| inst.encode())
        .flat_map(|(a, b, c)| [a.to_le_bytes(), b.to_le_bytes(), c.to_le_bytes()].concat())
        .collect::<Vec<_>>()
}

fn write_bind_template(instructions: Vec<InstructionInfo>) -> Result<String, Error> {
    let bind_count = instructions.len();
    let binding = instructions
        .into_iter()
        .map(|inst| inst.encode())
        .map(|(word0, word1, word2)| format!("{{{:#x},{:#x},{:#x}}},", word0, word1, word2))
        .collect::<String>();
    let mut output = String::new();
    output
        .write_fmt(format_args!(
            include_str!("templates/bind.h.template"),
            bind_count = bind_count,
            binding = binding,
        ))
        .context("Failed to format output")?;
    Ok(output)
}

fn read_file(path: &PathBuf) -> Result<String, Error> {
    let mut file = File::open(path)?;
    let mut buf = String::new();
    file.read_to_string(&mut buf)?;
    Ok(buf)
}

fn handle_command(command: Command) -> Result<(), Error> {
    match command {
        Command::Debug { options, device_file } => {
            let includes = handle_includes(options.include, options.include_file)?;
            let includes = includes.iter().map(read_file).collect::<Result<Vec<String>, _>>()?;
            let input = options.input.ok_or(anyhow!("The debug command requires an input."))?;
            let program = read_file(&input)?;
            let (instructions, symbol_table) = compiler::compile_to_symbolic(&program, &includes)?;

            let device = read_file(&device_file)?;
            let binds = offline_debugger::debug_from_str(&instructions, &symbol_table, &device)?;
            if binds {
                println!("Driver binds to device.");
            } else {
                println!("Driver doesn't bind to device.");
            }
            Ok(())
        }
        Command::Test { options, test_spec } => {
            let input = options.input.ok_or(anyhow!("The test command requires an input."))?;
            let program = read_file(&input)?;
            let includes = handle_includes(options.include, options.include_file)?;
            let includes = includes.iter().map(read_file).collect::<Result<Vec<String>, _>>()?;
            let test_spec = read_file(&test_spec)?;
            if !test::run(&program, &includes, &test_spec)? {
                return Err(anyhow!("Test failed"));
            }
            Ok(())
        }
        Command::Compile { options, output, depfile, disable_autobind, output_bytecode } => {
            let includes = handle_includes(options.include, options.include_file)?;
            handle_compile(
                options.input,
                includes,
                disable_autobind,
                output_bytecode,
                output,
                depfile,
            )
        }
        Command::Generate { options, output } => handle_generate(options.input, output),
    }
}

fn handle_includes(
    mut includes: Vec<PathBuf>,
    include_file: Option<PathBuf>,
) -> Result<Vec<PathBuf>, Error> {
    if let Some(include_file) = include_file {
        let file = File::open(include_file).context("Failed to open include file")?;
        let reader = io::BufReader::new(file);
        let mut filenames = reader
            .lines()
            .map(|line| line.map(PathBuf::from))
            .map(|line| line.context("Failed to read include file"))
            .collect::<Result<Vec<_>, Error>>()?;
        includes.append(&mut filenames);
    }
    Ok(includes)
}

fn handle_compile(
    input: Option<PathBuf>,
    includes: Vec<PathBuf>,
    disable_autobind: bool,
    output_bytecode: bool,
    output: Option<PathBuf>,
    depfile: Option<PathBuf>,
) -> Result<(), Error> {
    let mut output_writer: Box<dyn io::Write> = if let Some(output) = output {
        // If there's an output filename then we can generate a depfile too.
        if let Some(filename) = depfile {
            let mut file = File::create(filename).context("Failed to open depfile")?;
            let depfile_string =
                write_depfile(&output, &input, &includes).context("Failed to create depfile")?;
            file.write(depfile_string.as_bytes()).context("Failed to write to depfile")?;
        }
        Box::new(File::create(output).context("Failed to create output file")?)
    } else {
        Box::new(io::stdout())
    };

    let instructions = if !disable_autobind {
        let input = input.ok_or(anyhow!("An input is required when disable_autobind is false."))?;
        let program = read_file(&input)?;
        let includes = includes.iter().map(read_file).collect::<Result<Vec<String>, _>>()?;
        compiler::compile(&program, &includes)?
    } else if let Some(input) = input {
        // Autobind is disabled but there are some bind rules for manual binding.
        let program = read_file(&input)?;
        let includes = includes.iter().map(read_file).collect::<Result<Vec<String>, _>>()?;
        let mut instructions = compiler::compile(&program, &includes)?;
        instructions.insert(
            0,
            InstructionInfo::new(Instruction::Abort(Condition::NotEqual(AUTOBIND_PROPERTY, 0))),
        );
        instructions
    } else {
        // Autobind is disabled and there are no bind rules. Emit only the autobind check.
        vec![InstructionInfo::new(Instruction::Abort(Condition::NotEqual(AUTOBIND_PROPERTY, 0)))]
    };

    if output_bytecode {
        let bytecode = write_bind_bytecode(instructions);
        output_writer.write_all(bytecode.as_slice()).context("Failed to write to output file")?;
    } else {
        let template = write_bind_template(instructions)?;
        output_writer.write_all(template.as_bytes()).context("Failed to write to output file")?;
    };

    Ok(())
}

/// Converts a declaration to the FIDL constant format.
fn convert_to_fidl_constant(
    declaration: bind_library::Declaration,
    path: &String,
) -> Result<String, Error> {
    let mut result = String::new();
    let identifier_name = declaration.identifier.name.to_uppercase();

    // Generating the key definition is only done when it is not extended.
    // When it is extended, the key will already be defined in the library that it is
    // extending from.
    if !declaration.extends {
        writeln!(
            &mut result,
            "const NodePropertyKey {} = \"{}.{}\";",
            &identifier_name, &path, &identifier_name
        )?;
    }

    for value in declaration.values {
        let property_output = match &value {
            bind_library::Value::Number(name, val) => {
                let name = name.to_string().to_uppercase();
                format!("const NodePropertyValueUint {}_{} = {};", identifier_name, name, val)
            }
            bind_library::Value::Str(name, val) => {
                let name = name.to_string().to_uppercase();
                format!("const NodePropertyValueString {}_{} = \"{}\";", identifier_name, name, val)
            }
            bind_library::Value::Bool(name, val) => {
                let name = name.to_string().to_uppercase();
                format!("const NodePropertyValueBool {}_{} = {};", identifier_name, name, val)
            }
            bind_library::Value::Enum(name) => {
                let name = name.to_string().to_uppercase();
                format!("const NodePropertyValueEnum {}_{};", identifier_name, name)
            }
        };
        writeln!(&mut result, "{}", property_output)?;
    }

    Ok(result)
}

fn write_fidl_template(syntax_tree: bind_library::Ast) -> Result<String, Error> {
    // Get library path.
    let path = &syntax_tree.name.to_string();

    // Convert all key value pairs to their equivalent constants.
    let definition = syntax_tree
        .declarations
        .into_iter()
        .map(|declaration| convert_to_fidl_constant(declaration, path))
        .collect::<Result<Vec<String>, _>>()?
        .join("\n");

    // Output result into template.
    let mut output = String::new();
    output
        .write_fmt(format_args!(
            include_str!("templates/fidl.template"),
            path = path,
            definition = definition,
        ))
        .context("Failed to format output")?;

    Ok(output.to_string())
}

fn handle_generate(input: Option<PathBuf>, output: Option<PathBuf>) -> Result<(), Error> {
    let input = input.ok_or(anyhow!("An input is required."))?;
    let input_content = read_file(&input)?;

    // Generate the FIDL library.
    let keys = bind_library::Ast::try_from(input_content.as_str())
        .map_err(compiler::CompilerError::BindParserError)?;
    let template = write_fidl_template(keys)?;

    // Create and open output file.
    let mut output_writer: Box<dyn io::Write> = if let Some(output) = output {
        Box::new(File::create(output).context("Failed to create output file.")?)
    } else {
        // Output file name was not given. Print result to stdout.
        Box::new(io::stdout())
    };

    // Write FIDL library to output.
    output_writer.write_all(template.as_bytes()).context("Failed to write to output file")?;

    Ok(())
}

#[cfg(test)]
mod tests {
    use super::*;

    fn get_test_fidl_template(ast: bind_library::Ast) -> Vec<String> {
        write_fidl_template(ast)
            .unwrap()
            .split("\n")
            .map(|s| s.to_string())
            .filter(|x| !x.is_empty())
            .collect()
    }

    #[test]
    fn zero_instructions() {
        let bytecode = write_bind_bytecode(vec![]);
        assert!(bytecode.is_empty());

        let template = write_bind_template(vec![]).unwrap();
        assert!(template.contains("ZIRCON_DRIVER_BEGIN_PRIV(Driver, Ops, VendorName, Version, 0)"));
    }

    #[test]
    fn one_instruction() {
        let instructions = vec![InstructionInfo::new(Instruction::Match(Condition::Always))];
        let bytecode = write_bind_bytecode(instructions);
        assert_eq!(bytecode, vec![0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0]);

        let instructions = vec![InstructionInfo::new(Instruction::Match(Condition::Always))];
        let template = write_bind_template(instructions).unwrap();
        assert!(template.contains("ZIRCON_DRIVER_BEGIN_PRIV(Driver, Ops, VendorName, Version, 1)"));
        assert!(template.contains("{0x1000000,0x0,0x0}"));
    }

    #[test]
    fn disable_autobind() {
        let instructions = vec![
            InstructionInfo::new(Instruction::Abort(Condition::NotEqual(AUTOBIND_PROPERTY, 0))),
            InstructionInfo::new(Instruction::Match(Condition::Always)),
        ];
        let bytecode = write_bind_bytecode(instructions);
        assert_eq!(bytecode[..12], [2, 0, 0, 0x20, 0, 0, 0, 0, 0, 0, 0, 0]);

        let instructions = vec![
            InstructionInfo::new(Instruction::Abort(Condition::NotEqual(AUTOBIND_PROPERTY, 0))),
            InstructionInfo::new(Instruction::Match(Condition::Always)),
        ];
        let template = write_bind_template(instructions).unwrap();
        assert!(template.contains("ZIRCON_DRIVER_BEGIN_PRIV(Driver, Ops, VendorName, Version, 2)"));
        assert!(template.contains("{0x20000002,0x0,0x0}"));
    }

    #[test]
    fn depfile_no_includes() {
        let output = PathBuf::from("/a/output");
        let input = PathBuf::from("/a/input");
        assert_eq!(
            write_depfile(&output, &Some(input), &[]).unwrap(),
            "/a/output: /a/input\n".to_string()
        );
    }

    #[test]
    fn depfile_no_input() {
        let output = PathBuf::from("/a/output");
        let includes = vec![PathBuf::from("/a/include"), PathBuf::from("/b/include")];
        let result = write_depfile(&output, &None, &includes).unwrap();
        assert!(result.starts_with("/a/output:"));
        assert!(result.contains("/a/include"));
        assert!(result.contains("/b/include"));
    }

    #[test]
    fn depfile_input_and_includes() {
        let output = PathBuf::from("/a/output");
        let input = PathBuf::from("/a/input");
        let includes = vec![PathBuf::from("/a/include"), PathBuf::from("/b/include")];
        let result = write_depfile(&output, &Some(input), &includes).unwrap();
        assert!(result.starts_with("/a/output:"));
        assert!(result.contains("/a/input"));
        assert!(result.contains("/a/include"));
        assert!(result.contains("/b/include"));
    }

    #[test]
    fn zero_keys() {
        let empty_ast = bind_library::Ast::try_from("library fuchsia.platform;").unwrap();
        let template: Vec<String> = get_test_fidl_template(empty_ast);

        let expected = vec![
            "library fuchsia.platform.bind;".to_string(),
            "using fuchsia.driver.framework;".to_string(),
        ];

        assert!(template.into_iter().zip(expected).all(|(a, b)| (a == b)));
    }

    #[test]
    fn one_key() {
        let ast = bind_library::Ast::try_from(
            "library fuchsia.platform;\nstring A_KEY {\nA_VALUE = \"a string value\",\n};",
        )
        .unwrap();
        let template: Vec<String> = get_test_fidl_template(ast);

        let expected = vec![
            "library fuchsia.platform.bind;".to_string(),
            "using fuchsia.driver.framework;".to_string(),
            "const NodePropertyKey A_KEY = \"fuchsia.platform.A_KEY\";".to_string(),
            "const NodePropertyValueString A_KEY_A_VALUE = \"a string value\";".to_string(),
        ];

        println!("{:#?}\n\n", template);
        println!("{:#?}", expected);

        assert!(template.into_iter().zip(expected).all(|(a, b)| (a == b)));
    }

    #[test]
    fn one_key_extends() {
        let ast = bind_library::Ast::try_from(
            "library fuchsia.platform;\nextend uint fuchsia.BIND_PROTOCOL {\nBUS = 84,\n};",
        )
        .unwrap();
        let template: Vec<String> = get_test_fidl_template(ast);

        let expected = vec![
            "library fuchsia.platform.bind;".to_string(),
            "using fuchsia.driver.framework;".to_string(),
            "const NodePropertyValueUint BIND_PROTOCOL_BUS = 84;".to_string(),
        ];

        assert!(template.into_iter().zip(expected).all(|(a, b)| (a == b)));
    }

    #[test]
    fn lower_snake_case() {
        let ast = bind_library::Ast::try_from(
            "library fuchsia.platform;\nstring a_key {\na_value = \"a string value\",\n};",
        )
        .unwrap();
        let template: Vec<String> = get_test_fidl_template(ast);

        let expected = vec![
            "library fuchsia.platform.bind;".to_string(),
            "using fuchsia.driver.framework;".to_string(),
            "const NodePropertyKey A_KEY = \"fuchsia.platform.A_KEY\";".to_string(),
            "const NodePropertyValueString A_KEY_A_VALUE = \"a string value\";".to_string(),
        ];

        assert!(template.into_iter().zip(expected).all(|(a, b)| (a == b)));
    }
}
