/* 
 * Diplomová práce ÚSI VUT 
 * Forenzní analýza webového prohlížeče
 *
 * Autor: Michal Bača
 * Datum: 20.5.2015
 */
package yafft.Utils;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Collectors;

/**
 *
 * @author michal
 */
public class HostInfo {

    private final String hostOsName;
    private final String hostOsVersion;
    private final String userName;
    private final String userDir;
    private final Date date;

    private final String FFDefaultHomeDirLinux;
    private final String FFDefaultCacheDirLinux;

    private final String FFDefaultHomeDirWinXP;
    private final String FFDefaultCacheDirWinXP;

    private final String FFDefaultHomeDirWinVista;
    private final String FFDefaultCacheDirWinVista;

    private List<File> FFProfilePaths; ///seznam adresářů v /.mozilla/firefox
    private List<FFProfile> FFProfiles; //seznam profilů a souboů db k nim patřících
    private File FFProfilesInitFile;
    private Path FFPath;

    public HostInfo() throws IOException {
        this.FFDefaultHomeDirLinux = ".mozilla/firefox/";
        this.FFDefaultCacheDirLinux = ".cache/mozzila/firefox/";

        this.FFDefaultHomeDirWinXP = "\\Application Data\\Mozilla\\Firefox\\";
        this.FFDefaultCacheDirWinXP = "\\Application Data\\Mozilla\\Firefox\\";

        this.FFDefaultHomeDirWinVista = "\\AppData\\Roaming\\Mozilla\\Firefox\\";
        this.FFDefaultCacheDirWinVista = "\\AppData\\Roaming\\Mozilla\\Firefox\\";

        this.userDir = System.getProperty("user.home");
        this.userName = System.getProperty("user.name");
        this.hostOsName = System.getProperty("os.name");
        this.hostOsVersion = System.getProperty("os.version");
        this.date = new Date();

        if (this.isLinux()) {
            this.FFPath = Paths.get(this.userDir, this.FFDefaultHomeDirLinux);
        } else {
            this.FFPath = Paths.get(this.userDir, this.FFDefaultHomeDirWinVista);
        }

        this.updateProfilePaths();

    }

    public void setFFProfilePaths(List<File> FFProfilePaths) {
        this.FFProfilePaths = FFProfilePaths;
    }

    public void setFFProfiles(List<FFProfile> FFProfiles) {
        this.FFProfiles = FFProfiles;
    }

    public void setFFProfilesInitFile(File FFProfilesInitFile) {
        this.FFProfilesInitFile = FFProfilesInitFile;
    }

    public void setFFPath(Path FFPath) {
        this.FFPath = FFPath;
    }

    public void updateProfilePaths() {

        try {
            if (Files.exists(FFPath)) {
                this.FFProfilePaths = Files.walk(FFPath, 1).filter(Files::isDirectory).map(Path::toFile).collect(Collectors.toList());
               /* for (File f :FFProfilePaths) {
                 System.out.println("XXXXXXXXXXXXFiles " + f );
                }
                */
                
                this.FFProfilesInitFile = new File(this.FFPath + "profiles.ini");

                this.FFProfiles = new ArrayList<>();

                this.FFProfilePaths.stream().forEach((_item) -> {
                    System.out.print("Possible profile " + _item);
                    if (!_item.getName().toLowerCase().contains("crash") && !_item.getName().toLowerCase().contains("firefox") && !_item.getName().toLowerCase().contains(FFPath.getFileName().toString())) {
                        this.FFProfiles.add(new FFProfile(_item));
                         System.out.print(" OK\n");
                    }
                });

            } else {
                //this.FFPath = null;
                System.out.println("File '" + "'̈́ does NOT exist");
            }

        } catch (IOException ex) {
            Logger.getLogger(HostInfo.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public List<File> getFFProfilePaths() {
        return FFProfilePaths;
    }

    public List<FFProfile> getFFProfiles() {
        return FFProfiles;
    }

    public File getFFProfilesInitFile() {
        return FFProfilesInitFile;
    }

    public Path getFFPath() {
        if (FFPath != null) {
            return FFPath;
        } else {
            return Paths.get(userDir);
        }
    }

    public String getHostOsName() {
        return hostOsName;
    }

    public String getHostOsVersion() {
        return hostOsVersion;
    }

    public String getUserName() {
        return userName;
    }

    public String getUserDir() {
        return userDir;
    }

    public Date getDate() {
        return date;
    }

    public void printOsInfo() {
        System.out.println("Hostname: " + this.hostOsName + " " + this.hostOsVersion);
        System.out.println("User directory: " + this.userDir);
        System.out.println("FF path: " + this.getFFPath());

        System.out.println("FF profiles: " + FFProfiles.size());
        this.FFProfiles.stream().forEach((_item) -> {
            System.out.println(_item);
        });

        this.listProfilesFiles();

    }

    public Boolean isWindows() {
        return (this.hostOsName.indexOf("Win") >= 0);
    }

    public Boolean isLinux() {
        return (this.hostOsName.toLowerCase().indexOf("lin") >= 0);
    }

    public void listProfilesFiles() {
        //print path attribustes (creation time, modif time, acces time etc) size hash
        this.FFProfiles.stream().forEach((_item) -> {
            this.listProfileFiles(_item);

        });
    }

    public void listProfileFiles(FFProfile p) {
        try {
            //print path attribustes (creation time, modif time, acces time etc) size hash
            System.out.println("Profil: " + p.getProfile().getPath() + " " + p.getVersion());
            System.out.println("Creation Time\tSize\tRegular File\tName\tMD5\tSHA-256");
            Files.walk(p.getProfile().toPath()).collect(Collectors.toList()).forEach((Path f) -> {
                try {
                    BasicFileAttributes attr;
                    attr = Files.readAttributes(f, BasicFileAttributes.class);

                    System.out.println(attr.creationTime() + "\t" + attr.size() + "\t" + attr.isRegularFile() + "\t" + f + "\t" + Hash.getMD5(f) + "\t" + Hash.getSHA256(f));

                } catch (IOException ex) {
                    //Logger.getLogger(HostInfo.class.getName()).log(Level.SEVERE, null, ex);
                    System.out.println("File not found: " + f.toString());
                }

            });

        } catch (IOException ex) {
            //System.out.println("File not found:\n-->");
            Logger.getLogger(HostInfo.class.getName()).log(Level.SEVERE, null, ex);
        }

    }

    public List<Path> getProfileFiles(FFProfile p) {
        try {
            List<Path> files = Files.walk(p.getProfile().toPath()).collect(Collectors.toList());
            return files;
        } catch (IOException ex) {
            Logger.getLogger(HostInfo.class.getName()).log(Level.SEVERE, null, ex);
        }

        return null;
    }

}
