use std::env;
use std::fs;
use std::io::{stdout, Write};
use std::path::Path;
use std::os::unix::fs::PermissionsExt;

/*extern crate chrono;
use chrono::prelude::*;*/

fn main(){
    let args: Vec<String> = env::args().collect();
    // Flags vars
    let mut show_hidden = false;
    let mut show_prev_and_current = false;
    let mut long_listing = false;
    // Directories
    let pwd = env::current_dir().unwrap();
    let mut dir = pwd.to_str();
    for arg in 1..args.len() {
        match args[arg].as_str() {
            "--help" => {
                println!("List files in directory");
            },
            "-a" | "--all" => {
                show_hidden = true;
                show_prev_and_current = true;
            },
            "-A" | "--almost-all" => {
                show_hidden = true;
                show_prev_and_current = false;
            },
            "-l" => {
                long_listing = true;
            },
            arg => {
                dir = Some(arg);
            },
        }
    }
    list_dir(dir.unwrap().to_string(), show_hidden, show_prev_and_current, long_listing);
}         
fn list_dir(arg: String, show_hidden: bool, show_prev_and_current: bool, long_listing: bool) {
    let files = fs::read_dir(arg.clone()).unwrap();
    if show_hidden && show_prev_and_current {
        println!(".");
        println!("..");
    }
    for entry in files {
        let path = entry.unwrap().path();
        let file = path.strip_prefix(arg.clone());
        if file.clone().unwrap().display().to_string().starts_with('.') && !show_hidden {
            continue;
        }
        if long_listing {
            long_listing_format(Path::new(&path), file.unwrap().display().to_string());
        } else {
            print!("{} ", file.unwrap().display());
        }
    }
    if !long_listing {
        print!("\n");
    }
    stdout().flush().unwrap();
}

fn long_listing_format(path: &Path, file: String) -> std::io::Result<()> {
    let metadata = fs::metadata(path)?;
    let modified = metadata.modified();
    /*let timestamp = modified.parse::<i64>().unwrap();
    let naive = NaiveDateTime::fromtimestamp(timestamp, 0);
    let datetime: DateTime<Utc> = DateTime::from_utc(naive, Utc);*/
    let mut permissions_string = String::new();
    if metadata.is_dir() {
        permissions_string.push('d');
    } else {
        permissions_string.push('-');
    }
    println!("{}{:o} {} {}", permissions_string, metadata.permissions().mode(), metadata.len(), file);
    Ok(())
}
