package testslbmjava;

import java.io.File;
import java.util.HashMap;

import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;

import gov.sandia.gnem.slbmjni.GridProfile;
import gov.sandia.gnem.slbmjni.Point;
import gov.sandia.gnem.slbmjni.SLBMException;
import gov.sandia.gnem.slbmjni.SlbmInterface;

public class TestRSTTPathUnc
{
    private static SlbmInterface slbm;

    private static int verbosity = 1;

    private static HashMap<Point, GridProfile> profiles;

    @BeforeClass
    public static void setUpBeforeClass() throws Exception
    {
        File here = new File(".");
        System.out.println("Running from directory " + here.getCanonicalPath());

        // Load the c++ SLBM library libslbm.so into memory.
        try
        {
            System.loadLibrary("GeoTessCPP");
            System.loadLibrary("SLBM");
            System.loadLibrary("SLBMJNI");
        }
        catch (UnsatisfiedLinkError ex)
        {
            throw new Exception(ex.getMessage());
        }

        System.out.println("setUpBeforeClass()  slbmjni loaded");
        slbm = new SlbmInterface();

        System.out.println("SlbmInterface version " + slbm.getVersion());

//		slbm.loadVelocityModel("models/rstt.2.3");
//
//		profiles = new HashMap<Point, GridProfile>(slbm.getNGridNodes());
//
//		for (int i=0; i<slbm.getNGridNodes(); ++i)
//		{
//			GridProfile profile = slbm.getGridData(i);
//			profiles.put(new Point(profile), profile);
//		}
//
//		System.out.println("Profiles.size = "+profiles.size());

    }

    @AfterClass
    public static void tearDownAfterClass() throws Exception
    {
        slbm.close();
        if (verbosity > 0) System.out.println("Done");
    }

    @Test
    public void testGetVersion()
    {
        if (verbosity > 0)
            System.out.println("testGetVersion()");
        assert (slbm.getVersion().equals("3.0.5"));
    }

    @Test
    public void testValidatePathUncModel() throws SLBMException
    {

        String oldSLBMModelPath = "E:/PathUnc_Mike_Begnaud_Jul_8_2019/pathunc/rstt201903.geotess";
        String newSLBMModelPath = "E:/PathUnc_Mike_Begnaud_Jul_8_2019/pathunc/rstt201903_valid.geotess";
        String pathUncModelPath = "E:/PathUnc_Mike_Begnaud_Jul_8_2019/pathunc/rsttPathUnc2019_07.geotess";

        slbm.loadVelocityModel(pathUncModelPath);

    // choose an arbitrary phase (Pn, Pg, Sn, or Lg)
    String phase = "Pn";

    // arbitrary source (let's choose somewhere on the San Andreas fault)
    double srcLatDeg =   35.1361;  // latitude (degrees)
    double srcLonDeg = -119.6755;  // longitude (degrees)
    double srcDepKm  =   10;       // depth (km)

    // arbitrary receiver (let's choose the ANMO station in Albuquerque)
    double rcvLatDeg =   34.945911;  // latitude (degrees)
    double rcvLonDeg = -106.457199;  // longitude (degrees)
    double rcvDepKm  =   -1.820;     // depth (km)

    // print parameter information
    System.out.println("\n");
    System.out.println("Configuration:\n");
    System.out.println("-------------------------\n");
    System.out.println(String.format("         Phase:    %s\n", phase));
    System.out.println(String.format("Source   Lat:    %9.4f deg\n", srcLatDeg));
    System.out.println(String.format("Source   Lon:    %9.4f deg\n", srcLonDeg));
    System.out.println(String.format("Source   Depth:  %9.4f km\n",  srcDepKm));
    System.out.println(String.format("Receiver Lat:    %9.4f deg\n", rcvLatDeg));
    System.out.println(String.format("Receiver Lon:    %9.4f deg\n", rcvLonDeg));
    System.out.println(String.format("Receiver Depth:  %9.4f km\n",  rcvDepKm));


    // instantiate an RSTT object
    System.out.println("\n");
    System.out.println("Instantiating new RSTT object...\n");

    // convert lat/lon from degrees to radians
    double srcLatRad = Math.toRadians(srcLatDeg);
    double srcLonRad = Math.toRadians(srcLonDeg);
    double rcvLatRad = Math.toRadians(rcvLatDeg);
    double rcvLonRad = Math.toRadians(rcvLonDeg);

    // create a GreatCircle object from the source to the receiver
    System.out.println("Creating great circle path...\n");
    slbm.createGreatCircle(phase,
        srcLatRad, srcLonRad, srcDepKm,
        rcvLatRad, rcvLonRad, rcvDepKm);
    System.out.println("Performing RSTT...\n");

    // compute the distance from source to receiver
    double distRad = slbm.getDistance();        // compute distance
    double distDeg = Math.toDegrees(distRad);  // convert radians --> degrees

    // compute travel time
    double travelTimeSec = slbm.getTravelTime();  // compute travel time

    // compute travel time uncertainty
    double travelTimeUncSec = slbm.getTravelTimeUncertainty();  // compute travel time uncertainty

    // compute slowness
    double slownessSecPerRad = slbm.getSlowness();              // compute slowness
    double slownessSecPerDeg = Math.toRadians(slownessSecPerRad);  // convert radians --> degrees

    // compute slowness uncertainty
    double slownessUncSecPerRad = slbm.getSlownessUncertainty();                // compute slowness uncertainty
    double slownessUncSecPerDeg = Math.toRadians(slownessUncSecPerRad);  // convert radioans --> degrees

    // compute diff travel time w/respect to latitude
    double diffTravelTimePerLatSecPerRad = slbm.get_dtt_dlat();
    double diffTravelTimePerLatSecPerDeg = Math.toRadians(diffTravelTimePerLatSecPerRad);

    // compute diff travel time w/respect to longitude
    double diffTravelTimePerLonSecPerRad = slbm.get_dtt_dlon();
    double diffTravelTimePerLonSecPerDeg = Math.toRadians(diffTravelTimePerLonSecPerRad);

    // compute diff travel time w/respect to depth
    double diffTravelTimePerDepSecPerKm = slbm.get_dtt_ddepth();

    // print results
    System.out.println("\n");
    System.out.println("Results:\n");
    System.out.println("-------------------------\n");
    System.out.println(String.format("Distance:                  %9.4f deg\n", distDeg));
    System.out.println(String.format("Travel Time:               %9.4f sec\n", travelTimeSec));
    System.out.println(String.format("Travel Time Uncertainty:   %9.4f sec\n", travelTimeUncSec));
    System.out.println(String.format("Slowness:                  %9.4f sec/deg\n", slownessSecPerDeg));
    System.out.println(String.format("Slowness Uncertainty:      %9.4f sec/deg\n", slownessUncSecPerDeg));
    System.out.println(String.format("diff Travel Time / Lat:    %9.4f sec/deg\n", diffTravelTimePerLatSecPerDeg));
    System.out.println(String.format("diff Travel Time / Lon:    %9.4f sec/deg\n", diffTravelTimePerLonSecPerDeg));
    System.out.println(String.format("diff Travel Time / Depth:  %9.4f sec/km\n\n", diffTravelTimePerDepSecPerKm));


    //grid.getActiveNodeId(nodeids[i]) to get actual node id from weights

//		profiles = new HashMap<Point, GridProfile>(slbm.getNGridNodes());
//
//		for (int i=0; i<slbm.getNGridNodes(); ++i)
//		{
//			GridProfile profile = slbm.getGridData(i);
//			profiles.put(new Point(profile), profile);
//		}
//
//		System.out.println("Profiles.size = "+profiles.size());

    }
}
