
package vypocetObalky;

import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
import org.json.JSONException;

/**
 *
 * @author Filip Dvorak
 */
public class VypocetObalky {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) throws IOException, FileNotFoundException, JSONException {
        //1.nejpre se zjisti ma IP adresa z programu ifconfig na stanici PlanetLab
        //2.zjisti se poloha OB v poli podle zjistene IP adresy uzlu, kde bezi tento program
        //3.provede se ping k ostatnim serverum - uzlum site PlanetLab
        //4.Cas z pingu se priradi k jejich IP adresam
        //5.Spocita vzdalenosti k ostatnim uzlum  
        //6.Vypocita se obalka a ulozi se do souboru
 
        //program je ted urcen pro TEST na lokalnim pocitaci s napevno zadanou IP adresou
        // v pripade nasazeni na server je nutno odkomentovat radek pod slovem SERVER
        // a zakomentovat radek pod slovem TEST
        
        //smazani log souboru
        Log.smazSouborLog();
        Log.zapisDoLogu("Log smazan");
        
        
        System.out.println("Spustim...");
        //1.
        //Pro nasazeni na server odkomentovat nasledujici radek - SERVER
        // funkce pro zjisteni IP adresy uzlu na kterem bezi program
        //String mojeIPAdresa = VstupniData.najdiMojiIP();
        System.out.println("Nacitam landmarks.txt");
        //vytvoreni pole s uzly planetlabu (OB)- typ orientacni uzel (souradnice a IP adresa)- nactenim ze souboru
        ArrayList<OrientacniBod> uzlyPlanetLab = VstupniData.vytvorOrienatcniBodyZeSouboru();
        
        //pro TEST na lokalnim PC - je zde napavno nastavena IP adresa OB
        String mojeIPAdresa = "155.245.47.225";

      
        //2. aktualni orientacni bod je ten ze ktereho bude spusten ping k ostatnim orientacnim uzlum 
        OrientacniBod aktualniOrientacniBod = VstupniData.najdiAktualniPolohuOrientacnihoBodu(mojeIPAdresa, uzlyPlanetLab);

        //3.4.  fce najdiZpozdeniKOrientacnimBodum vrati pole s hodnotami orientacnibod (souradnice, ip adresa) a zpozdeni
        ArrayList<ZpozdeniKOrientacnimuBodu> zpozdeniKOrientacnimBodum = VstupniData.najdiZpozdeniKOrientacnimBodum(uzlyPlanetLab);
        //System.out.println("Vypocet vzdalenosti");
        System.out.println("Vypocet vzdalenosti od " + aktualniOrientacniBod.getIp().getIpAdresa().toString());
        
        //5.Spocita vzdalenosti k ostatnim uzlum a ulozi ho do pole zpozdeniKOrientacnimBodum k IP adresam  
        zpozdeniKOrientacnimBodum = Vypocty.VypocetVzdalenostiKOrientacnimBodum(aktualniOrientacniBod.getSouradnice(), zpozdeniKOrientacnimBodum);
        
        //fce pro kontrolu nulovych pingu --- pokud je ping 0.0 nelze stanici pingnout a tudiz priradit zpozdeni
        ArrayList<ZpozdeniKOrientacnimuBodu> zpozdeniKOrientacnimBodumBezNulovychPing = Vypocty.vyradNulovePingy(zpozdeniKOrientacnimBodum);
        
        //pokud je stanice vzdalena 0km je z pole take ostranena
        ArrayList<ZpozdeniKOrientacnimuBodu> zpozdeniKOrientacnimBodumBezNulovychPingANulovychVzdalenosti = Vypocty.vyradNuloveVzdalenosti(zpozdeniKOrientacnimBodumBezNulovychPing);
        
        //z pole vymaze stejne body -- tz. se stejnou IP adresou
        //ArrayList<ZpozdeniKOrientacnimuBodu> zpozdeniKOrientacnimBodumKonecne = Vypocty.vyradStejneIP(zpozdeniKOrientacnimBodumBezNulovychPingANulovychVzdalenosti);

        System.out.println("Vytvarim graf zpozdeni/vzdalenost");
        
        //Vytvori graf zpozdeni/vzdalenost
        ArrayList<Souradnice> grafH = Vypocty.vytvorGraf(zpozdeniKOrientacnimBodumBezNulovychPingANulovychVzdalenosti);
        ArrayList<Souradnice> grafS = Vypocty.vytvorGraf(zpozdeniKOrientacnimBodumBezNulovychPingANulovychVzdalenosti);
       
                
        //pro TEST na lokalnim PC - napevno zadana data do grafu zpozdeni/vzdalenost
        ArrayList<Souradnice> pokusH = new ArrayList<Souradnice>();
        ArrayList<Souradnice> pokusD = new ArrayList<Souradnice>();
        
        pokusH.add(new Souradnice(600, 200));
        pokusH.add(new Souradnice(900, 350));
        pokusH.add(new Souradnice(1200, 400));
        pokusH.add(new Souradnice(1500, 500));
        pokusH.add(new Souradnice(1800, 800));
        pokusH.add(new Souradnice(2100, 920));
        pokusH.add(new Souradnice(2400, 1250));
        pokusH.add(new Souradnice(2700, 1300));
        pokusH.add(new Souradnice(3000, 1450));
        
        pokusD.add(new Souradnice(600, 200));
        pokusD.add(new Souradnice(900, 350));
        pokusD.add(new Souradnice(1200, 400));
        pokusD.add(new Souradnice(1500, 500));
        pokusD.add(new Souradnice(1800, 800));
        pokusD.add(new Souradnice(2100, 920));
        pokusD.add(new Souradnice(2400, 1250));
        pokusD.add(new Souradnice(2700, 1300));
        pokusD.add(new Souradnice(3000, 1450));
        
        //vyradi orientacni body, ktere maji stejne souradnice
        ArrayList<Souradnice> grafHNovy = Vypocty.vyradStejneSouradnice(grafH);
        ArrayList<Souradnice> grafSNovy = Vypocty.vyradStejneSouradnice(grafS);


        //fce jenz oreze body, ktere maji vzdalenost vyssi nez ktrerou muze urazit signal 2/3  rychlosti svetla
        ArrayList<Souradnice> grafHorniNovaOmezenaRychlostiDvetla = Vypocty.vyradRychlejsiBody(grafHNovy);
        ArrayList<Souradnice> grafDolniNovaOmezenaRychlostiDvetla = Vypocty.vyradRychlejsiBody(grafSNovy);

        //vypis souradnic z grafu
        for (Souradnice souradnice : grafHorniNovaOmezenaRychlostiDvetla) {
            System.out.println("grafhorni :" + souradnice.getSouradniceX() + " " + souradnice.getSouradniceY());
            Log.zapisDoLogu("grafhorni :" + souradnice.getSouradniceX() + " " + souradnice.getSouradniceY());
            
        }

        for (Souradnice souradnice : grafDolniNovaOmezenaRychlostiDvetla) {
            System.out.println("grafdolni :" + souradnice.getSouradniceX() + " " + souradnice.getSouradniceY());
            Log.zapisDoLogu("grafdolni :" + souradnice.getSouradniceX() + " " + souradnice.getSouradniceY());
        }

        //vypocet komplexni obalky
        System.out.println("Vypocitavam horni obalku");
        // pro TEST na lokalnim PC
        ArrayList<Primka> obalkaHorniNova1 = VypocetObalkyNove.horniObalka(pokusD);
        //pro test na SERVERU
        //ArrayList<Primka> obalkaHorniNova1 = VypocetObalkyNove.horniObalka(grafHorniNovaOmezenaRychlostiDvetla);
        
        System.out.println("Vypocitavam spodni obalku");
        // pro TEST na lokalnim PC
         ArrayList<Primka> obalkaSpodniNova1 = VypocetObalkyNove.dolniObalka(pokusH);
         //pro test na SERVERU
        //ArrayList<Primka> obalkaHorniNova1 = VypocetObalkyNove.horniObalka(grafDolniNovaOmezenaRychlostiDvetla);
        

        System.out.println("Tvorim soubory");
        //Vytvoreni souboru pro zapis grafu apod.
        // pro test na SERVERU
        //Writer vystupHorni = new BufferedWriter(new FileWriter("/home/cesnet_vutbr2/xdvora02/obalkaHorni.txt"));
        //Writer vystupSpodni = new BufferedWriter(new FileWriter("/home/cesnet_vutbr2/xdvora02/obalkaDolni.txt"));
        //pro TEST na lokalnim PC
        Writer vystupHorni = new BufferedWriter(new FileWriter("obalkaHorni.txt"));
        Writer vystupSpodni = new BufferedWriter(new FileWriter("obalkaDolni.txt"));


        //soubor se zapisem zpozdeni a souradnic orientacniho bodu
        // pro test na SERVERU
        //Writer zpozdeniSoubor = new BufferedWriter(new FileWriter("/home/cesnet_vutbr2/xdvora02/zpozdeni.txt"));
        //pro TEST na lokalnim PC
        Writer zpozdeniSoubor = new BufferedWriter(new FileWriter("zpozdeni.txt"));
        
        //soubor, kde bude zapsan graf serazeny
        // pro TEST na lokalnim PC
        Writer grafSerazenyHorni = new BufferedWriter(new FileWriter("grafH.txt"));
        Writer grafSerazenyDolni = new BufferedWriter(new FileWriter("grafD.txt"));
        // pro test na SERVERU
        //Writer grafSerazenyHorni = new BufferedWriter(new FileWriter("/home/cesnet_vutbr2/xdvora02/grafH.txt"));
        //Writer grafSerazenyDolni = new BufferedWriter(new FileWriter("/home/cesnet_vutbr2/xdvora02/grafD.txt"));

        //v kazdem cyklu bude primka odpovidat jednomu radku v obalkaHorni
        //zapise do souboru ---format je bodA bodB,k,q     
        try {
            for (Primka primka : obalkaHorniNova1) {
                vystupHorni.write(primka.getA().getSouradniceX() + " " + primka.getA().getSouradniceY() + " " + primka.getB().getSouradniceX() + " " + primka.getB().getSouradniceY() + " " + primka.getK() + " " + primka.getQ() + "\r\n");
            }
        } finally {
            //uzavreni souboru
            vystupHorni.close();
        }
        try {
            for (Primka primka : obalkaSpodniNova1) {
                vystupSpodni.write(primka.getA().getSouradniceX() + " " + primka.getA().getSouradniceY() + " " + primka.getB().getSouradniceX() + " " + primka.getB().getSouradniceY() + " " + primka.getK() + " " + primka.getQ() + "\r\n");
            }
        } finally {
            vystupSpodni.close();

        }

        try {
            for (ZpozdeniKOrientacnimuBodu aktualniZpozdeniKOrientacnimuBodu : zpozdeniKOrientacnimBodumBezNulovychPingANulovychVzdalenosti) {
                zpozdeniSoubor.write(aktualniZpozdeniKOrientacnimuBodu.getOrientacniBod().getIp().getIpAdresa().toString() + " " + aktualniZpozdeniKOrientacnimuBodu.getVzdalenost() + " " + aktualniZpozdeniKOrientacnimuBodu.getZpozdeni() + "\r\n");

            }
        } finally {
            zpozdeniSoubor.close();
        }

        try {
            for (Souradnice aktualniBod : grafHNovy) {
                grafSerazenyHorni.write(aktualniBod.getSouradniceX() + " " + aktualniBod.getSouradniceY() + "\r\n");
            }
        } finally {
            grafSerazenyHorni.close();
        }
        try {
            for (Souradnice aktualniBod : grafSNovy) {
                grafSerazenyDolni.write(aktualniBod.getSouradniceX() + " " + aktualniBod.getSouradniceY() + "\r\n");
            }
        } finally {
            grafSerazenyDolni.close();
        }


    }
}
