package be.iminds.ilabt.jfed.scanner;

import java.net.MalformedURLException;
import java.net.URL;
import java.security.cert.X509Certificate;
import java.util.Map;

/**
 * AuthorityTypeFinder
 */
public class AuthorityTypeFinder {
    public static ServerScanner.ScannedInformation<AuthorityType> findTypeFromUrl(String urlStr) {
        ServerScanner.ScannedInformation<AuthorityType> res = new ServerScanner.ScannedInformation<>();
        if (urlStr.contains("protogeni/xmlrpc")) res.add(ServerScanner.ScanCertainty.GOOD_GUESS, AuthorityType.EMULAB);
        if (urlStr.contains("foam/gapi")) res.add(ServerScanner.ScanCertainty.GOOD_GUESS, AuthorityType.FOAM);
        if (urlStr.contains("protogeni")) res.add(ServerScanner.ScanCertainty.GOOD_GUESS, AuthorityType.EMULAB);
        if (urlStr.contains("foam")) res.add(ServerScanner.ScanCertainty.GOOD_GUESS, AuthorityType.FOAM);
        if (urlStr.contains("gapi")) res.add(ServerScanner.ScanCertainty.GUESS, AuthorityType.FOAM);
        if (urlStr.contains("orca/xmlrpc")) res.add(ServerScanner.ScanCertainty.GOOD_GUESS, AuthorityType.ORCA);
        if (urlStr.contains("orca")) res.add(ServerScanner.ScanCertainty.GOOD_GUESS, AuthorityType.ORCA);

        try {
            URL url = new URL(urlStr);
            int port = url.getPort();
            if (port == 3626) res.add(ServerScanner.ScanCertainty.GUESS, AuthorityType.FOAM);
            if (port == 12346) res.add(ServerScanner.ScanCertainty.GUESS, AuthorityType.SFAWRAP);
            if (port == 12345) res.add(ServerScanner.ScanCertainty.GUESS, AuthorityType.SFAWRAP);
            if (port == 12369) res.add(ServerScanner.ScanCertainty.GUESS, AuthorityType.EMULAB);
            if (port == 11443) res.add(ServerScanner.ScanCertainty.GUESS, AuthorityType.ORCA);
            if (port == 5001) res.add(ServerScanner.ScanCertainty.GUESS, AuthorityType.FOAM);
            if (port == 8001) res.add(ServerScanner.ScanCertainty.GUESS, AuthorityType.GCF);
        } catch (MalformedURLException e) {
            //ignore
        }

        return res;
    }
    public static ServerScanner.ScannedInformation<AuthorityType> findTypeFromUrn(String urn) {
        ServerScanner.ScannedInformation<AuthorityType> res = new ServerScanner.ScannedInformation<>();
        if (urn.contains("foam")) res.add(ServerScanner.ScanCertainty.GUESS, AuthorityType.FOAM);
        if (urn.contains("exogeni")) res.add(ServerScanner.ScanCertainty.GOOD_GUESS, AuthorityType.ORCA);
        if (urn.contains("instageni")) res.add(ServerScanner.ScanCertainty.GOOD_GUESS, AuthorityType.EMULAB);
        if (urn.contains("openflow")) res.add(ServerScanner.ScanCertainty.GUESS, AuthorityType.FOAM);
        if (urn.contains("gcf")) res.add(ServerScanner.ScanCertainty.GUESS, AuthorityType.GCF);
        return res;
    }

    /**
     * @param getVersionData The "value" Map of a successful GetVersion reply. (assumed AM GetVersion call)
     * */
    public static ServerScanner.ScannedInformation<AuthorityType> findTypeFromGetVersionReply(Map getVersionData) {
        ServerScanner.ScannedInformation<AuthorityType> res = new ServerScanner.ScannedInformation<>();
        if (getVersionData == null) return null;
//        "code": {
//                     "geni_code": 0,
//                     "am_type": "gcf2",
//                     "am_
        if (getVersionData.containsKey("code") && getVersionData.get("code") instanceof Map) {
            Map code = (Map) getVersionData.get("code");
            if (code.containsKey("am_type")) {
                String amType = code.get("am_type")+"";
                if (amType.equalsIgnoreCase("emulab") || amType.equalsIgnoreCase("protogeni")) res.add(ServerScanner.ScanCertainty.CONFIRMED, AuthorityType.EMULAB);
                if (amType.equalsIgnoreCase("sfa")) res.add(ServerScanner.ScanCertainty.GOOD_GUESS, AuthorityType.SFAWRAP);
                if (amType.equalsIgnoreCase("gcf") || amType.equalsIgnoreCase("gcf2")) res.add(ServerScanner.ScanCertainty.CONFIRMED, AuthorityType.GCF);
            }
        }

        if (getVersionData.containsKey("value") && getVersionData.get("value") instanceof Map) {
            Map value = (Map) getVersionData.get("value");
            if (value.containsKey("foam_version")) res.add(ServerScanner.ScanCertainty.CONFIRMED, AuthorityType.FOAM);
            if (value.containsKey("sfa")) res.add(ServerScanner.ScanCertainty.GUESS, AuthorityType.SFAWRAP);
        }

        return res;
    }


    public static ServerScanner.ScannedInformation<AuthorityType> findTypeFromCert(X509Certificate certificate) {
        //TODO
        return null;
    }
}
