package be.iminds.ilabt.jfed.experimenter_gui.util;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Map;

/**
 * User: twalcari
 * Date: 6/25/2015
 * Time: 16:57
 */
public class URIUtils {
    private static final Logger LOG = LoggerFactory.getLogger(URIUtils.class);

    public static final String JFED_URI_SCHEME = "jfed";
    private static final String UTF_8 = "UTF-8";

    private URIUtils() {

    }

    @Nullable
    public static Map<String, String> processJFedUri(@Nonnull String uriString) {
        if(uriString.endsWith("/")) {
            LOG.debug("Removing trailing slash from URI");
            uriString = uriString.substring(0, uriString.length() - 1);
        }
        try {
            URI uri = new URI(uriString);

            if (JFED_URI_SCHEME.equalsIgnoreCase(uri.getScheme())) {
                String schemeSpecificPart = uri.getSchemeSpecificPart();
                if (schemeSpecificPart.startsWith("//")) {
                    schemeSpecificPart = schemeSpecificPart.substring(2);
                }

                LOG.debug("Found a jFed-URI with the following contents: {}", schemeSpecificPart);

                Map<String, String> namedParameters = new HashMap<>();

                String[] nameValuePairs = schemeSpecificPart.split("&");

                for (String nameValuePair : nameValuePairs) {
                    int splitIndex = nameValuePair.indexOf("=");

                    if (splitIndex >= 0) {
                        String name = nameValuePair.substring(0, splitIndex);
                        String value = nameValuePair.substring(splitIndex + 1);

                        //do the necessary decoding
                        try {
                            name = URLDecoder.decode(name, UTF_8);
                            value = URLDecoder.decode(value, UTF_8);
                        } catch (UnsupportedEncodingException e) {
                            LOG.error("Could not decode URI-parts", e);
                        }

                        if (namedParameters.containsKey(name)) {
                            LOG.warn("URI '{}' was already registered with value '{}'. Ignoring new value '{}'",
                                    name, namedParameters.get(name), value);
                        } else {
                            namedParameters.put(name, value);
                        }
                    } else {
                        LOG.warn("Could not parse parameter '{}'. Skipping.", nameValuePair);
                    }
                }

                return namedParameters;
            } else {
                LOG.warn("Encountered an URI, but with an unexpected scheme '{}'. Ignoring", uri.getScheme());
                return null;
            }

        } catch (URISyntaxException ex) {
            LOG.error("Received startup parameter '{}', but could not process it.", uriString, ex);
            return null;
        }


    }

}
