/*
*   loadenv: a small, zero-dependency dotenv implementation for rust
*   Copyright (C) 2020 Ben Galusha
*
*   This program is free software: you can redistribute it and/or modify
*   it under the terms of the GNU General Public License as published by
*   the Free Software Foundation, either version 3 of the License, or
*   (at your option) any later version.
*
*   This program is distributed in the hope that it will be useful,
*   but WITHOUT ANY WARRANTY; without even the implied warranty of
*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*   GNU General Public License for more details.
*
*   You should have received a copy of the GNU General Public License
*   along with this program.  If not, see <https://www.gnu.org/licenses/>.
*/

//! A simple, zero-dependency [dotenv](https://github.com/bkeepers/dotenv)
//! implementation for Rust. Use this library to load environment variables
//! from a `.env` file into your program's environment.

use std::env;
use std::fs::File;
use std::io::{BufRead, BufReader};

mod parse;
use parse::parse;

/// Finds and loads a `.env` from [`env::current_dir()`].
///
/// - If a `.env` file is not present, this returns `false`.
/// - If a `.env` file is found and loaded successfully, this
/// returns `true`.
///
/// # Panics
///
/// If a `.env` file exists but cannot be read, [`load()`] will panic.
///
/// # Examples
///
/// ```
/// use loadenv;
///
/// loadenv::load().ok();
/// ```
pub fn load() -> Result<bool, String> {
    let mut path = env::current_dir().unwrap();
    path.push(".env");

    if !path.is_file() {
        return Ok(false);
    }

    let file = File::open(path).unwrap();
    let mut reader = BufReader::new(file);
    load_buf(&mut reader)?;
    Ok(true)
}

/// Load a `.env` from a [`BufReader`].
///
///
/// # Panics
///
/// If the `.env` file contained in `reader` cannot be read, [`load_buf()`] will panic.
///
/// # Examples
/// ```
/// use loadenv;
///
/// let dotenv = "FOO=bar\nBOP==baz";
/// loadenv::load_buf(dotenv.as_bytes()).ok();
/// ```
pub fn load_buf<R: BufRead>(reader: R) -> Result<(), String> {
    let pairs = parse(reader)?;
    for (k, v) in pairs.iter() {
        if env::var(k).is_err() {
            env::set_var(k, v);
        }
    }
    Ok(())
}
