package hhtznr;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.CookieHandler;
import java.net.CookieManager;
import java.net.CookiePolicy;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.nio.file.Paths;
import java.util.Base64;
import java.util.Properties;

import org.openstreetmap.josm.data.Preferences;
import org.openstreetmap.josm.spi.preferences.Config;
import org.openstreetmap.josm.tools.Http1Client;
import org.openstreetmap.josm.tools.HttpClient;

public class JosmNasaEarthdataAuthTest {

    /*
     * Prefix used to identify redirects to URS for the purpose of adding
     * authentication headers.
     */
    public static final String URS = "https://urs.earthdata.nasa.gov";

    public static void main(String[] args) {
        Preferences prefs = Preferences.main();
        Config.setPreferencesInstance(prefs);
        HttpClient.setFactory(Http1Client::new);

        String resource1 = "https://e4ftl01.cr.usgs.gov/MEASURES/SRTMGL3.003/2000.02.11/N44E010.SRTMGL3.hgt.zip.xml";
        String resource2 = "https://e4ftl01.cr.usgs.gov/MEASURES/SRTMGL3.003/2000.02.11/N44E011.SRTMGL3.hgt.zip.xml";
        String[] resources = { resource1, resource2 };

        String username;
        String password;
        File propFile = Paths
                .get(Preferences.main().getDirs().getPreferencesDirectory(false).toString(), "nasa_earthdata_urs.properties")
                .toFile();
        Properties prop = new Properties();
        try {
            prop.load(new FileInputStream(propFile));
            username = prop.getProperty("username");
            password = prop.getProperty("password");
            System.out.println("NASA URS: username = " + username);
        } catch (IOException e) {
            e.printStackTrace();
            return;
        }
        String authHeader = "Basic "
                + Base64.getEncoder().encodeToString((username + ":" + password).getBytes(StandardCharsets.UTF_8));

        /*
         * Set up a cookie handler to maintain session cookies. A custom CookiePolicy
         * could be used to limit cookies to just the resource server and URS.
         */
        CookieHandler.setDefault(new CookieManager(null, CookiePolicy.ACCEPT_ALL));

        for (String resource : resources) {
            System.out.println("Accessing resource " + resource);
            try {

                /* Retrieve a stream for the resource */
                InputStream in = getResource(resource, authHeader);
                /* Dump the resource out (not a good idea for binary data) */
                BufferedReader bin = new BufferedReader(new InputStreamReader(in));
                String line;
                while ((line = bin.readLine()) != null) {
                    System.out.println(line);
                }
                bin.close();
            } catch (Exception e) {
                System.out.println("ERROR: Failed to retrieve resource");
                System.out.println(e.getMessage());
                e.printStackTrace();
            }
            System.out.println();
        }
    }

    public static InputStream getResource(String resource, String authHeader) throws Exception {
        int maxRedirects = 10;
        HttpClient httpClient = HttpClient.create(new URL(resource));
        httpClient.setMaxRedirects(maxRedirects);
        httpClient.useCache(false);

        HttpClient.Response response = httpClient.connect(null, URS, authHeader);

        if (response.getResponseCode() == HttpURLConnection.HTTP_OK)
            return response.getContent();
        else
            throw new Exception("Server responded: " + response.getResponseCode() + " - " + response.getResponseCode());
    }
}
