use std::env;
use std::fs;
use std::fmt::Debug;
use std::io;
use std::io::Write;
use std::path::Path;
use std::str;


/// Primary object used to write constant files.
/// 
/// # Example
/// ```no_run
/// # use std::path::Path;
/// # #[derive(Debug)]
/// # struct Point { x: u8, y: u8 }
/// use build_const::ConstWriter;
/// 
/// // use `for_build` in `build.rs`
/// let mut consts = ConstWriter::from_path(
///     &Path::new("/tmp/constants.rs")
/// ).unwrap();
/// 
/// // add an external dependency (`use xyz::Point`)
/// consts.add_dependency("xyz::Point");
/// 
/// // finish dependencies and starting writing constants
/// let mut consts = consts.finish_dependencies();
///
/// // add an array of values
/// let values: Vec<u8> = vec![1, 2, 3, 36];
/// consts.add_array("ARRAY", "u8", &values);
///
/// // Add a value that is a result of "complex" calculations
/// consts.add_value("VALUE", "u8", values.iter().sum::<u8>());
/// 
/// // Add a value from an external crate (must implement `Debug`)
/// consts.add_value("VALUE", "Point", &Point { x: 3, y: 7});
/// ```
pub struct ConstWriter {
    f: fs::File,
}

/// Created from `ConstWriter::finish_dependencies`. See
/// documentation for `ConstWriter`.
pub struct ConstValueWriter {
    f: fs::File,
}

impl ConstWriter {
    /// Create a ConstWriter to be used for your crate's `build.rs`
    pub fn for_build(mod_name: &str) -> io::Result<ConstWriter> {
        let out_dir = env::var("OUT_DIR").unwrap();
        let mod_name = format!("{}.rs", mod_name);
        let dest_path = Path::new(&out_dir).join(mod_name);

        Ok(ConstWriter {
            f: fs::File::create(&dest_path)?
        })
    }

    /// Create a new ConstWriter to write to an path. If a file
    /// already exists at the path then it will be deleted.
    pub fn from_path(path: &Path) -> io::Result<ConstWriter> {
        let f = fs::OpenOptions::new()
            .write(true)
            .truncate(true)
            .open(path)?;
        Ok(ConstWriter {
            f: f,
        })
    }

    /// finish writing dependencies and start writing constants
    pub fn finish_dependencies(self) -> ConstValueWriter {
        ConstValueWriter { f: self.f }
    }

    /// Add a dependency to your constants file.
    pub fn add_dependency(&mut self, lib: &str) {
        write!(self.f, "pub use {};\n", lib).unwrap();
    }

    /// Add a raw string to the constants file.
    /// 
    /// This method only changes `raw` by adding a `\n` at the end.
    pub fn add_raw(&mut self, raw: &str) {
        write!(self.f, "{}\n", raw).unwrap();
    }

}

impl ConstValueWriter {
    /// Add a value to the constants file.
    /// 
    /// You have to manually specify the `name`, type (`ty`) and `value`
    /// of the constant you want to add.
    /// 
    /// The `value` uses the `Debug` trait to determine the formating of
    /// the value being added. If `Debug` is not accurate or will not work,
    /// you must use `add_value_raw` instead and format it yourself.
    pub fn add_value<T: Debug>(&mut self, name: &str, ty: &str, value: T) {
        self.add_value_raw(name, ty, &format!("{:?}", value));
    }

    /// Add a pre-formatted value to the constants file.
    /// 
    /// `add_value` depends on `Debug` being implemented in such a way
    /// that it accurately represents the type's creation. Sometimes that
    /// cannot be relied on and `add_value_raw` has to be used instead.
    pub fn add_value_raw(&mut self, name: &str, ty: &str, raw_value: &str) {
        write!(
            self.f, "pub const {}: {} = {};\n", 
            name, 
            ty,
            raw_value,
        ).unwrap();
    }

    /// Add an array of len > 0 to the constants
    /// 
    /// You have to manually specify the `name`, type (`ty`) of the **items** and 
    /// `values` of the array constant you want to add. The length of the array
    /// is determined automatically.
    /// 
    /// Example: `const.add_array("foo", "u16", &[1,2,3])`
    /// 
    /// The `value` of each item uses the `Debug` trait to determine the 
    /// formatting of the value being added. If `Debug` is not accurate or will 
    /// not work, you must use `add_array_raw` instead and format it yourself.
    pub fn add_array<T: Debug>(&mut self, name: &str, ty: &str, values: &[T]) {
        write_array(&mut self.f, name, ty, values);
    }

    /// Add an array of pre-formatted values to the constants file. The length of the array is
    /// determined automatically.
    /// 
    /// `add_array` depends on `Debug` being implemented for each item in such a way that it
    /// accurately represents the item's creation. Sometimes that cannot be relied on and
    /// `add_array_raw` has to be used instead.
    pub fn add_array_raw(&mut self, name: &str, ty: &str, raw_values: &[&str]) {
        write_array_raw(&mut self.f, name, ty, raw_values);
    }

    /// Add a raw string to the constants file.
    /// 
    /// This method only changes `raw` by adding a `\n` at the end.
    pub fn add_raw(&mut self, raw: &str) {
        write!(self.f, "{}\n", raw).unwrap();
    }

    /// Finish writing to the constants file and consume self.
    pub fn finish(&mut self) {
        self.f.flush().unwrap();
    }

}

// Public Functions

/// Write an array and return the array's full type representation.
/// 
/// This can be used to create nested array constant types.
pub fn write_array<T: Debug, W: Write>(w: &mut W, name: &str, ty: &str, values: &[T]) 
    -> String
{
    assert!(
        !values.is_empty(), 
        "attempting to add an array of len zero. If this is intentional, use \
        add_value_raw instead."
    );
    let full_ty = write_array_header(w, name, ty, values.len());
    for v in values.iter() {
        write_array_item_raw(w, &format!("{:?}", v));
    }
    write_array_end(w);
    full_ty
}

/// Write an array of raw values and return the array's full type representation.
/// 
/// This can be used to create nested array constant types.
pub fn write_array_raw<W: Write>(
        w: &mut W, name: &str, ty: &str, raw_values: &[&str]
    ) 
    -> String
{
    assert!(
        !raw_values.is_empty(), 
        "attempting to add an array of len zero. If this is intentional, use \
        add_value_raw instead."
    );
    let full_ty = write_array_header(w, name, ty, raw_values.len());
    for &v in raw_values {
        write_array_item_raw(w, v);
    }
    write_array_end(w);
    full_ty
}

// Helpers

/// Write the array header and return the array's full type.
fn write_array_header<W: Write>(w: &mut W, name: &str, ty: &str, len: usize) -> String {
    let full_ty = format!("[{}; {}]", ty, len);
    write!(w, "pub const {}: {} = [\n", name, &full_ty).unwrap();
    full_ty
}

fn write_array_item_raw<W: Write>(w: &mut W, raw_item: &str) {
    write!(w, "    {},\n", raw_item).unwrap()
}

fn write_array_end<W: Write>(w: &mut W) {
    write!(w, "];\n").unwrap();
}
