use super::types::LicenseFile;
use super::Error;
use std::path::PathBuf;
mod xml;

pub enum LZ4State {
    None,
    AlreadyCompressed,
    Compress,
}

pub struct CDAudioFile {
    pub file_path: PathBuf,
    pub align:     bool,
}

impl CDAudioFile {
    pub fn new(file_path: PathBuf, align: bool) -> CDAudioFile {
        CDAudioFile{file_path, align}
    }
}

pub struct Configuration {
    pub publisher:           Option<String>,
    pub license_file:        LicenseFile,
    pub backup_license_file: LicenseFile,
    pub root:                Directory,
    pub cd_audio_files:      Vec<CDAudioFile>,
    pub lead_out_sectors:    Option<usize>,
}

impl Configuration {
    pub fn new() -> Configuration {
        Configuration{publisher: None, license_file: LicenseFile::None, backup_license_file: LicenseFile::None, root: Directory::new("root", false), cd_audio_files: Vec::new(), lead_out_sectors: None}
    }
}

pub struct CommonProperties {
    pub name:        String,
    pub is_hidden:   bool,
    pub lz4_state:   LZ4State,
    pub padded_size: Option<usize>,    
}

pub enum FileKind {
    Regular,
    Main(PathBuf),
    Overlay(PathBuf),
    XAAudio(Vec<PathBuf>),
}

pub struct File {
    pub common: CommonProperties,
    pub path:   PathBuf,
    pub kind:   FileKind
}
pub struct Directory {
    pub name:      String,
    pub is_hidden: bool,
        member:    Vec<DirMember>,
}

impl Directory {
    pub fn new(name: &str, is_hidden: bool) -> Directory {
        Directory{name: String::from(name), is_hidden, member: Vec::new()}
    }

    pub fn add_file(&mut self, file: File) {
        self.member.push(DirMember::File(file));
    }

    pub fn add_dir(&mut self, dir: Directory) {
        self.member.push(DirMember::Directory(dir));
    }

    pub fn into_iter(self) -> std::vec::IntoIter<DirMember> {
        self.member.into_iter()
    }
}

pub enum DirMember {
    File(File),
    Directory(Directory),
} 

pub fn parse_xml(xml: String) -> Result<Configuration, Error> {
    Ok(xml::parse(xml)?)
}