// Copyright 2020 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 message ID generator for the `strings.xml` format
//!
//! This crate contains a binary `strings_to_fidl`, which generates message IDs from the
//! Android-formatted [strings.xml resource file][strings-xml], as a set of FIDL constants.
//! Complete support is not a specific goal, rather the generator will be amended to include more
//! features as more features are needed.
//!
//! [strings-xml]: https://developer.android.com/guide/topics/resources/string-resource

// TODO(fmil): temporary, until all code is used.
#![allow(dead_code)]

use {
    anyhow::Context,
    anyhow::Error,
    anyhow::Result,
    intl_strings::{message_ids, parser, veprintln},
    std::env,
    std::fs::File,
    std::io,
    std::path::PathBuf,
    structopt::StructOpt,
};

// TODO(fmil): Add usage link here.
#[derive(Debug, StructOpt)]
#[structopt(name = "Extracts information from strings.xml into FIDL")]
struct Args {
    #[structopt(long = "input", help = "The path to the input strings.xml format file")]
    input: PathBuf,
    #[structopt(long = "output", help = "The path to the output FIDL file")]
    output: PathBuf,
    #[structopt(long = "verbose", help = "Verbose output, for debugging")]
    verbose: bool,
    #[structopt(
        long = "library",
        default_value = "fuchsia.intl.l10n",
        help = "The FIDL library name for which to generate the code"
    )]
    library: String,
}

/// Open the needed files, and handle usual errors.
fn open_files(args: &Args) -> Result<(impl io::Read, impl io::Write), Error> {
    let input_str = args.input.to_str().with_context(|| {
        format!("input filename is not utf-8, what? Use --verbose flag to print the value.")
    })?;
    let input = io::BufReader::new(
        File::open(&args.input)
            .with_context(|| format!("could not open input file: {}", input_str))?,
    );
    let output_str = args.output.to_str().with_context(|| {
        format!("output filename is not utf-8, what? Use --verbose flag to print the value.")
    })?;
    let output = File::create(&args.output)
        .with_context(|| format!("could not open output file: {}", output_str))?;
    Ok((input, output))
}

fn run(args: Args) -> Result<()> {
    veprintln!(args.verbose, "args: {:?}", args);

    let (input, mut output) = open_files(&args).with_context(|| "while opening files")?;
    let reader = parser::Instance::reader(input);

    let mut parser = parser::Instance::new(args.verbose);
    let dictionary = parser.parse(reader).with_context(|| "while parsing dictionary")?;
    let model = message_ids::from_dictionary(dictionary, &args.library)?;
    message_ids::render(model, &mut output)
}

fn main() -> Result<()> {
    env::set_var("RUST_BACKTRACE", "full");
    run(Args::from_args())
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::fs;
    use std::io::Write;
    use tempfile;

    // This test is only used to confirm that a program call generates some
    // output that looks meaningful.  Refer to the unit tests in the library
    // for tests that actually enforce the specification.
    #[test]
    fn basic() -> Result<(), Error> {
        let en = tempfile::NamedTempFile::new()?;
        write!(
            en.as_file(),
            r#"
               <?xml version="1.0" encoding="utf-8"?>
               <resources>
                 <!-- comment -->
                 <string
                   name="string_name"
                     >string</string>
               </resources>

            "#
        )
        .with_context(|| "while writing 'en' tempfile")?;

        let output = tempfile::NamedTempFile::new()?;

        let args = Args {
            input: en.path().to_path_buf(),
            output: output.path().to_path_buf(),
            verbose: false,
            library: "some_lib".to_string(),
        };

        run(args)?;

        let outcome = fs::read_to_string(output.path())?;
        assert_eq!(
            r#"// Generated by strings_to_fidl. DO NOT EDIT!

library some_lib;

enum MessageIds : uint64 {
    // 'string'
    STRING_NAME = 7134240810508078445;
};
"#,
            outcome
        );
        Ok(())
    }

    #[test]
    fn reader_config() -> Result<(), Error> {
        let en = tempfile::NamedTempFile::new()?;
        write!(
            en.as_file(),
            r#"
               <!-- comment is not allowed before ?xml? -->
               <?xml version="1.0" encoding="utf-8"?>
               <resources>
                 <!-- comment -->
                 <string
                   name="string_name"
                     >string</string>
               </resources>

            "#
        )
        .with_context(|| "while writing 'en' tempfile")?;

        let output = tempfile::NamedTempFile::new()?;

        let args = Args {
            input: en.path().to_path_buf(),
            output: output.path().to_path_buf(),
            verbose: false,
            library: "some_lib".to_string(),
        };

        match run(args) {
            Ok(_) => Err(anyhow::anyhow!("unexpected OK")),
            Err(_) => Ok(()),
        }
    }
}
