package mephisto;

import java.util.Scanner;
import java.io.*;
import java.util.Arrays;

/**
 *
 * @author ptribble
 *
 * Notes:
 *
 * delete() - It always deletes the array but does show the correct .
 * mdstatchecker() - it will scan line by line in /etc/mdstat. If the device is found on the line and the partition, checker should be changed to a 1. however, this is not working correctly.
 */
public class swraid {

    private static String raidlevel;
    private static String[] devices = new String[1000];
    private static String mddevice;
    private static String mdadm1 = "mdadm --create /dev/";
    private static String mdadm2 = " --level=";
    private static String mdadm3 = " --raid-devices=";
    private static StringBuffer alldevices = new StringBuffer(10000);
    private static int raiddevicecounter = 0;
    private static int checker = 0;

    public static void swraid() {
    }

    public static void drivers() {
        MephUtil.shell("modprobe raid1");
        MephUtil.shell("modprobe raid5");
        MephUtil.shell("modprobe raid6");
        MephUtil.shell("modprobe raid10");
        MephUtil.shell("modprobe dm-mod");
        if (MephUtil.filechecker("/tmp/mdadm.conf")) {
        } else {
            if (MephUtil.filechecker("/dev/md0")) {
                MephUtil.shell("rm -f /dev/md0");
            }
        }
    }

    public static void mdstatchecker(String device, String what) {
        checker = 0;
        String devicee = null;
        int j = device.length();
        if (j < 4) {
            devicee = device;
        } else {
            devicee = device.substring(6, j);
        }
        int k = what.length();
        String whate = what.substring(6, k);
        try {
            FileReader frr = new FileReader("/proc/mdstat");
            BufferedReader bfrr = new BufferedReader(frr);
            String read = null;
            while ((read = bfrr.readLine()) != null) {
                if (read.contains(devicee)) {
                    checker++;
                    if (read.contains(whate)) {
                        checker++;
                    } else {
                        checker = 0;
                    }
                }
            }
        } catch (Exception ads) {
        }
    }

    public static String getRaidlevel() {
        return raidlevel;
    }

    public static void setRaidlevel(String string) {
        raidlevel = string;
    }

    public static String getMDevice() {
        return mddevice;
    }

    public static void setDevice(String string) {
        mddevice = string;
    }

    public static void menu() {
        if (!Settings.getRoot()) {
            Menu.halfmenu();
            MephUtil.messageparser("\n\nError: You must be root for this action.", 0);
            Menu.pause();
            return;
        }
        drivers();
        mdadmchecker();
        int i = 0;
        while (i == 0) {
            Menu.halfmenu();
            MephUtil.messageparser("\nMephisto Backup Software RAID Utility.\n\nPlease verify your configuation with \"View RAID status\" to ensure that\n your changes are in effect.", 0);
            MephUtil.messageparser("\n1. View RAID status", 0);
            MephUtil.messageparser("2. Create RAID configuration.", 0);
            MephUtil.messageparser("3. View partition list.", 0);
            MephUtil.messageparser("4. Delete Array.", 0);
            MephUtil.messageparser("5. Run the partitioner utility.", 0);
            MephUtil.messageparser("6. Generate mdadmin.conf", 0);
            MephUtil.messageparser("7. Add drives to array.", 0);
            MephUtil.messageparser("8. Remove drive from array.", 0);
            MephUtil.messageparser("9. Exit this utility.", 0);
            MephUtil.messageparser("\nYour selection: ", 0);
            MephUtil.userinputparser();
            String choice = Settings.getInput();

            if (choice.contains(("1"))) {
                mdstat();
            } else if (choice.contains(("2"))) {
                create();
            } else if (choice.contains(("3"))) {
                partlayout();
            } else if (choice.contains(("4"))) {
                delete();
            } else if (choice.contains(("5"))) {
                Part.gatherInfo();
            } else if (choice.contains(("6"))) {
                configfile();
            } else if (choice.contains(("7"))) {
                add();
            } else if (choice.contains(("8"))) {
                remove();
            } else if (choice.contains(("9"))) {
                i = 1;
            } else {
                Menu.invalidselection();
            }
        }
    }

    public static void mdadmchecker() {
        if (MephUtil.filechecker("/sbin/mdadm")) {
        } else {
            Menu.halfmenu();
            MephUtil.messageparser("\n\nEror: mdadm not found!", 0);
            Menu.pause();
            System.exit(-1);
        }
    }

    public static void mdstat() {
        Menu.halfmenu();
        MephUtil.filechecker("/proc/mdstat", "\nError: mdstat not found!");
        MephUtil.shell("cat /proc/mdstat");
        Menu.pause();
    }

    public static void restore() {
        Menu.halfmenu();
        MephUtil.messageparser("\nNow that your RAID is configured and mounted, Mephisto will launch the restore process.", 0);
        MephUtil.messageparser("\n\nDo you wish to proceede? (y/n): ", 0);
        MephUtil.userinputparser();
        String choice = Settings.getInput();
        if (choice.contains(("n"))) {
        } else {
            restore.restore();
        }
    }

    public static void configfile() {
        Menu.halfmenu();
        MephUtil.writernoappend("/tmp/raidscan", "\n#!/bin/bash\nmdadm --detail --scan --verbose > /tmp/mdadm.conf");
        MephUtil.filecheckerDie("/tmp/raidscan");
        MephUtil.shell("bash /tmp/raidscan");
        MephUtil.filecheckerDie("/tmp/mdadm.conf");
        MephUtil.messageparser("\nRAID configuration saved as /tmp/mdadm.conf.\n\nMephisto will copy this over to the /etc/ folder on your new system\n\nafter the restore process is finished.", 0);
        Menu.pause();
        //return;
    }

    public static void partlayout() {
        Menu.halfmenu();
        MephUtil.shell("cat /proc/partitions");
        Menu.pause();
    }

    public static void remove() {
        Menu.halfmenu();
        MephUtil.messageparser("\n\nPress ! followed by enter to return to the menu.", 0);
        MephUtil.messageparser("\n\nRAID device to remove a drive from: ", 0);
        MephUtil.userinputparser();
        setDevice(Settings.getInput());
        if (getMDevice().contains(("!"))) {
        } else {
            MephUtil.filecheckerDie(getMDevice());
            Menu.halfmenu();
            MephUtil.messageparser("\nWhich partition would you like remove from:  " + getMDevice() + " : ", 0);
            MephUtil.userinputparser();
            String device = Settings.getInput();
            MephUtil.filecheckerDie(device);
            Menu.halfmenu();
            MephUtil.shell("mdadm --manage " + getMDevice() + " -f " + device);
            MephUtil.shell("mdadm --manage " + getMDevice() + " -r " + device);
            mdstatchecker(getMDevice(), device);
            if (checker == 2) {
                Menu.halfmenu();
                MephUtil.messageparser("\nError: Drive: " + device + " has not been removed from:  " + getMDevice(), 0);
                Menu.pause();
                configfile();
            } else {
                Menu.halfmenu();
                MephUtil.messageparser("\nDrive: " + device + " has been removed from:  " + getMDevice(), 0);
                Menu.pause();
                configfile();
            }
        }
    }

    public static void add() {
        Menu.halfmenu();
        MephUtil.messageparser("\n\nPress ! followed by enter to return to the menu.", 0);
        MephUtil.messageparser("\n\nRAID device to add a drive to: ", 0);
        MephUtil.userinputparser();
        setDevice(Settings.getInput());
        if (getMDevice().contains(("!"))) {
        } else {
            MephUtil.filecheckerDie(getMDevice());
            Menu.halfmenu();
            MephUtil.messageparser("\nWhich partition would you like to add to: " + getMDevice() + " : ", 0);
            MephUtil.userinputparser();
            String device = Settings.getInput();
            MephUtil.filecheckerDie(device);
            Menu.halfmenu();
            MephUtil.shell("mdadm --manage " + getMDevice() + " -a " + device);
            mdstatchecker(getMDevice(), device);
            if (checker == 2) {
                Menu.halfmenu();
                MephUtil.messageparser("\nDrive: " + device + " has been added to:  " + getMDevice()  + ". However, it may not be visible with mdadm until after a reboot.", 0);
                Menu.pause();
                configfile();
            } else {
                Menu.halfmenu();
                MephUtil.messageparser("\n\nError: Drive has not been added to: " + getMDevice() + ". An error or operation may be in place preventing the drive from being added.", 0);
                Menu.pause();
            }
        }
    }

    public static void delete() {
        Menu.halfmenu();
        MephUtil.messageparser("\n\nMephisto will now delete the array of your choosing.", 0);
        MephUtil.messageparser("\n\nPress ! followed by enter to return to the menu.", 0);
        MephUtil.messageparser("\n\nRAID volume to delete: ", 0);
        MephUtil.userinputparser();
        setDevice(Settings.getInput());
        if (getMDevice().contains(("!"))) {
        } else {
            MephUtil.filecheckerDie(getMDevice());
            Menu.halfmenu();
            MephUtil.shell("mdadm --manage " + getMDevice() + " -S");
            mdstatchecker(getMDevice(), "active");
            if (checker == 2) {
                Menu.halfmenu();
                MephUtil.messageparser("\n\nError: Volume: " + getMDevice() + " has not been deleted.", 0);
                Menu.pause();
            } else {
                Menu.halfmenu();
                MephUtil.messageparser("\n" + getMDevice() + " has been deleted.", 0);
                Menu.pause();
                configfile();
            }
        }
    }

    public static void format() {
        Menu.halfmenu();
        MephUtil.messageparser("\n\nPress ! followed by enter to return to the menu.", 0);
        MephUtil.messageparser("\n\nRAID volume to format: ", 0);
        MephUtil.userinputparser();
        setDevice(Settings.getInput());
        if (getMDevice().contains(("!"))) {
        } else {
            MephUtil.filecheckerDie(getMDevice());
            Menu.halfmenu();
            MephUtil.messageparser("\nFile system for new RAID device: ", 0);
            MephUtil.userinputparser();
            String filesystem = Settings.getInput();
            Menu.halfmenu();
            String formatstring = ("mkfs." + filesystem + " -I 128 /dev/" + getMDevice());
            Menu.pause();
        }
    }

    public static void create() {
        //Clears out existing data
        for (int g = 0; g != devices.length; g++) {
            devices[g] = null;
        }
        alldevices.delete(0, alldevices.length());

        int progress = 0;
        raiddevicecounter = 0;
        int i = 0;
        Menu.halfmenu();
        MephUtil.messageparser("\n\nMephisto will now try to create a new RAID device. \n\nPlease ensure that the device name is the same as your prior system to avoid errors.\n\nAlso, before resuming the restore process, ensure that the array build is complete by viewing the RAID status.\n\nPress ! followed by enter to return to the menu", 0);
        MephUtil.messageparser("\n\nName for new RAID device (Example: md0,md1) : ", 0);
        MephUtil.userinputparser();
        setDevice(Settings.getInput());
        if (getMDevice().contains(("!"))) {
        } else {
            while (progress != 1) {
                Menu.halfmenu();
                MephUtil.messageparser("\nPlease type the device name for each hard drive that you want to add to the array.\n\n Type done followed by enter to stop adding devices.", 0);
                MephUtil.messageparser("\n\nHard drive devices to add (Example:/dev/sda1) : ", 0);
                MephUtil.userinputparser();
                String add = Settings.getInput();
                if (add.contains("done")) {
                    progress = 1;
                } else {
                    i++;
                    devices[i] = add;
                }
            }
            Menu.halfmenu();
            MephUtil.messageparser("\n\nRaid Level: ", 0);
            MephUtil.userinputparser();
            setRaidlevel(Settings.getInput());

            int len = devices.length;
            for (int j = 0; j != len; j++) {
                if (devices[j] == null) {
                } else {
                    if (j > 0) {
                        raiddevicecounter++;
                        alldevices.append(" " + devices[j]);
                    }
                }
            }

            Menu.halfmenu();
            MephUtil.messageparser("\nOutput from mdadm:\n ", 0);
            MephUtil.shell(mdadm1 + getMDevice() + mdadm2 + getRaidlevel() + mdadm3 + raiddevicecounter + " " + alldevices + " --run");
            mdstatchecker(getMDevice(), "active");
            if (checker == 2) {
                Menu.halfmenu();
                MephUtil.messageparser("\nDevice: " + getMDevice() + " has been created!", 0);
                Menu.pause();
                configfile();
            } else {
                Menu.halfmenu();
                MephUtil.messageparser("\nError: " + getMDevice() + " has not been created!", 0);
                Menu.pause();
            }
        }
    }
}

