package SBC;

import com.sun.jna.Platform;

import java.io.File;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class SystemInformation {



    public static int getCPUTemperature() {
        if (Platform.isLinux()){
            File ff = new File("/sys/class/thermal/thermal_zone0/temp");
            if (ff.isFile() && ff.canRead()){
                try{
                    String value = Files.readString(ff.toPath()).trim();
                    return Integer.parseInt(value) / 1000;
                } catch (Exception ignored) {
                }
            }
        }
        return 0;
    }

    public static NetworkTransmitReceiveInfo[] getNetworkTransmitReceiveInfo(){
        if (Platform.isLinux()){
            File ff = new File("/proc/net/dev");
            if (ff.isFile() && ff.canRead()){
                List<NetworkTransmitReceiveInfo> result = new ArrayList<>();
                final Pattern pattern = Pattern.compile("\\s+(.*):\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)");
                try{
                    String[] lines = Files.readString(ff.toPath()).split("\n");
                    for (String line : lines){
                        Matcher m = pattern.matcher(line);
                        if (m.find()){
                            NetworkTransmitReceiveInfo info = new NetworkTransmitReceiveInfo();
                            info.name = m.group(1).trim();
                            info.bytesReceived = Long.parseLong(m.group(2));
                            info.packetsReceived = Long.parseLong(m.group(3));
                            info.errorsReceived = Long.parseLong(m.group(4));
                            info.droppedReceived = Long.parseLong(m.group(5));
                            info.fifoReceived = Long.parseLong(m.group(6));
                            info.frameReceived = Long.parseLong(m.group(7));
                            info.compressedReceived = Long.parseLong(m.group(8));
                            info.multicastReceived = Long.parseLong(m.group(9));
                            info.bytesTransmitted = Long.parseLong(m.group(10));
                            info.packetsTransmitted = Long.parseLong(m.group(11));
                            info.errorsTransmitted = Long.parseLong(m.group(12));
                            info.droppedTransmitted = Long.parseLong(m.group(13));
                            info.fifoTransmitted = Long.parseLong(m.group(14));
                            info.collsTransmitted = Long.parseLong(m.group(15));
                            info.carrierTransmitted = Long.parseLong(m.group(16));
                            info.compressedTransmitted = Long.parseLong(m.group(17));
                            info.timetick = System.currentTimeMillis();
                            result.add(info);
                        }
                    }
                } catch (Exception ignored) {

                }
                return result.toArray(new NetworkTransmitReceiveInfo[0]);
            }
        }
        return new NetworkTransmitReceiveInfo[0];
    }

    public static CpuInfo getCPUInfo(){
        CpuInfo result = new CpuInfo();
        if (Platform.isLinux()){
            File ff = new File("/proc/cpuinfo");
            if (ff.isFile() && ff.canRead()){
                final Pattern pattern = Pattern.compile( "\\s*(.*):\\s*(.*)");
                try{
                    String[] lines = Files.readString(ff.toPath()).split("\n");
                    for (String line : lines){
                        Matcher m = pattern.matcher(line);
                        if (m.find()){
                            String key = m.group(1).trim();
                            String value = m.group(2).trim();
                            switch (key){
                                case "processor":
                                    result.processorCount++;
                                    break;
                                case "Revision":
                                    result.revision = value;
                                    break;
                                case "Serial":
                                    result.serial = value;
                                    break;
                                case "Model":
                                    result.model = value;
                                    break;
                            }
                        }
                    }
                } catch (Exception ignored) {
                }
            }
        }
        return result;
    }

    public static ProcessorStatus[] getProcStat(){
        if (Platform.isLinux()){
            File ff = new File("/proc/stat");
            if (ff.isFile() && ff.canRead()){
                final Pattern pattern = Pattern.compile( "(cpu\\d?)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)");
                List<ProcessorStatus> result = new ArrayList<>();
                try{
                    String[] lines = Files.readString(ff.toPath()).split("\n");
                    for (String line : lines){
                        Matcher m = pattern.matcher(line);
                        if (m.find()){
                            ProcessorStatus info = new ProcessorStatus();
                            info.name = m.group(1).trim();
                            info.user = Integer.parseInt(m.group(2));
                            info.nice = Integer.parseInt(m.group(3));
                            info.system = Integer.parseInt(m.group(4));
                            info.idle = Integer.parseInt(m.group(5));
                            info.iowait = Integer.parseInt(m.group(6));
                            info.irq = Integer.parseInt(m.group(7));
                            info.softirq = Integer.parseInt(m.group(8));
                            info.steal = Integer.parseInt(m.group(9));
                            info.guest = Integer.parseInt(m.group(10));
                            info.guest_nice = Integer.parseInt(m.group(11));
                            result.add(info);
                        }
                    }
                    return result.toArray(new ProcessorStatus[0]);
                } catch (Exception ignored) {
                }
            }
        }
        return new ProcessorStatus[0];
    }

    public static RamInformation getRAMInformation(){

        RamInformation result = new RamInformation();
        if (Platform.isLinux()){
            File ff = new File("/proc/meminfo");
            if (ff.isFile() && ff.canRead()){
                final Pattern pattern = Pattern.compile("(.*):\\s+(\\d+).kB");
                try{
                    String[] lines = Files.readString(ff.toPath()).split("\n");
                    for (String line : lines) {
                        Matcher m = pattern.matcher(line);
                        if (m.find()){
                            String key = m.group(1);
                            int value = Integer.parseInt(m.group(2));
                            switch (key){
                                case "MemTotal":
                                    result.totalKB = value;
                                    break;
                                case "MemAvailable":
                                    result.availableKB = value;
                                    break;
                                case "SwapTotal":
                                    result.swapTotalKB = value;
                                    break;
                                case "SwapFree":
                                    result.swapFreeKB = value;
                                    break;
                            }
                        }
                    }
                } catch (Exception ignored) {
                }
                result.usedKB = result.totalKB - result.availableKB;
            }
        }
        return result;
    }
}
