package ru.yandex.wmconsole.util;

import org.jetbrains.annotations.NotNull;
import ru.yandex.misc.enums.EnumResolver;

import java.net.IDN;

/**
 * @author aherman
 */
public class BackportedWebmasterHostId {
    public static final int DEFAULT_HTTP_PORT = 80;
    public static final int DEFAULT_HTTPS_PORT = 443;
    public static final String IDN_FLAG = "xn--";

    @NotNull
    protected final Schema schema;
    @NotNull
    protected final String punycodeHostname;
    protected final int port;

    public BackportedWebmasterHostId(@NotNull Schema schema, @NotNull String punycodeHostname, int port) {
        this.schema = schema;
        this.punycodeHostname = punycodeHostname.toLowerCase();
        this.port = port;
    }

    @NotNull
    public Schema getSchema() {
        return schema;
    }

    @NotNull
    public String getPunycodeHostname() {
        return punycodeHostname;
    }

    public String getReadableHostname() {
        if (isIDN()) {
            return IDN.toUnicode(punycodeHostname);
        } else {
            return punycodeHostname;
        }
    }

    public int getPort() {
        return port;
    }

    public boolean isDefaultPort() {
        return port == schema.getDefaultPort();
    }

    public boolean isIDN() {
        return punycodeHostname.startsWith(IDN_FLAG) || punycodeHostname.contains("." + IDN_FLAG);
    }

    public static enum Schema {
        HTTP("http://", "http", DEFAULT_HTTP_PORT),
        HTTPS("https://", "https", DEFAULT_HTTPS_PORT),
        ;

        private final String schemaPrefix;
        private final String schemaName;
        private final int defaultPort;

        Schema(String schemaPrefix, String schemaName, int defaultPort) {
            this.schemaPrefix = schemaPrefix;
            this.schemaName = schemaName;
            this.defaultPort = defaultPort;
        }

        public String getSchemaPrefix() {
            return schemaPrefix;
        }

        public String getSchemaName() {
            return schemaName;
        }

        public int getDefaultPort() {
            return defaultPort;
        }

        public static final EnumResolver<Schema> R = EnumResolver.er(Schema.class);
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        BackportedWebmasterHostId that = (BackportedWebmasterHostId) o;

        if (port != that.port) return false;
        if (!punycodeHostname.equals(that.punycodeHostname)) return false;
        if (schema != that.schema) return false;

        return true;
    }

    @Override
    public int hashCode() {
        int result = schema.hashCode();
        result = 31 * result + punycodeHostname.hashCode();
        result = 31 * result + port;
        return result;
    }

    @Override
    public String toString() {
        return toStringId();
    }

    public String toStringId() {
        return schema.getSchemaName() + ':' + punycodeHostname + ':' + port;
    }
}
