// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package io.v.impl.google.naming;

import com.google.common.base.CharMatcher;
import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableList;
import com.google.common.net.HostAndPort;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import io.v.v23.naming.Endpoint;
import io.v.v23.naming.RoutingId;
import io.v.v23.rpc.NetworkAddress;

public class EndpointImpl implements Endpoint {
    private static final Pattern hostPortPattern = Pattern.compile("^(?:\\((.*)\\)@)?([^@]+)$");

    private final String protocol;
    private final String address;
    private final List<String> routes;
    private final RoutingId routingId;
    private final List<String> blessingNames;
    private final boolean isMountTable;
    private final boolean isLeaf;

    // TODO(suharshs): Remove endpoint 5 when the transition to endpoint 6 is complete.

    public static Endpoint fromString(String s) {
        Matcher matcher = hostPortPattern.matcher(s);
        if (matcher.matches()) {
            List<String> blessings = new ArrayList<>(1);
            // If the endpoint does not end in a @, it must be in [blessing@]host:port format.
            HostAndPort hostPort = HostAndPort.fromString(matcher.group(matcher.groupCount()));
            if (matcher.group(1) != null) {
                blessings.add(matcher.group(1));
            }

            return new EndpointImpl("", hostPort.toString(), ImmutableList.<String>of(), RoutingId.NULL_ROUTING_ID,
                    blessings, true, false);
        }

        if (s.endsWith("@@")) {
            s = s.substring(0, s.length() - 2);
        }
        if (s.startsWith("@")) {
            s = s.substring(1, s.length());
        }

        List<String> parts = Splitter.on('@').splitToList(s);
        int version = Integer.parseInt(parts.get(0));
        switch (version) {
            case 5:
                return fromV5String(parts);
            case 6:
                return fromV6String(parts);
            default:
                return null;
        }
    }

    private static Endpoint fromV5String(List<String> parts) {
        if (parts.size() < 5) {
            throw new IllegalArgumentException(
                    "Invalid format for endpoint, expecting 5 '@'-separated components");
        }

        String protocol = parts.get(1);
        String address = unescapeAddress(parts.get(2));
        if (address.isEmpty()) {
            address = ":0";
        }
        RoutingId routingId = RoutingId.fromString(parts.get(3));
        String mountTableFlag = parts.get(4);
        boolean isMountTable;
        boolean isLeaf;
        if ("".equals(mountTableFlag)) {
            isMountTable = true;
            isLeaf = false;
        } else if ("l".equals(mountTableFlag)) {
            isMountTable = false;
            isLeaf = true;
        } else if ("m".equals(mountTableFlag)) {
            isMountTable = true;
            isLeaf = false;
        } else if ("s".equals(mountTableFlag)) {
            isMountTable = false;
            isLeaf = false;
        } else {
            throw new IllegalArgumentException("Invalid mounttable flag " + mountTableFlag +
                    ", should be one of 'l', 'm' or 's'");
        }

        List<String> blessings;
        if ("".equals(parts.get(5))) {
            blessings = ImmutableList.of();
        } else {
            blessings = Splitter.on(',').splitToList(
                    Joiner.on("@").join(parts.subList(5, parts.size())));
        }
        return new EndpointImpl(protocol, address, ImmutableList.<String>of(), routingId, blessings, isMountTable, isLeaf);
    }

    private static Endpoint fromV6String(List<String> parts) {
        if (parts.size() < 6) {
            throw new IllegalArgumentException(
                    "Invalid format for endpoint, expecting 6 '@'-separated components");
        }

        String protocol = parts.get(1);
        String address = unescapeAddress(parts.get(2));
        if (address.isEmpty()) {
            address = ":0";
        }
        List<String> routes = unescapeRoutes(Splitter.on(',').splitToList(parts.get(3)));
        RoutingId routingId = RoutingId.fromString(parts.get(4));
        String mountTableFlag = parts.get(5);
        boolean isMountTable;
        boolean isLeaf;
        if ("".equals(mountTableFlag)) {
            isMountTable = true;
            isLeaf = false;
        } else if ("l".equals(mountTableFlag)) {
            isMountTable = false;
            isLeaf = true;
        } else if ("m".equals(mountTableFlag)) {
            isMountTable = true;
            isLeaf = false;
        } else if ("s".equals(mountTableFlag)) {
            isMountTable = false;
            isLeaf = false;
        } else {
            throw new IllegalArgumentException("Invalid mounttable flag " + mountTableFlag +
                    ", should be one of 'l', 'm' or 's'");
        }

        List<String> blessings;
        if ("".equals(parts.get(6))) {
            blessings = ImmutableList.of();
        } else {
            blessings = Splitter.on(',').splitToList(
                    Joiner.on("@").join(parts.subList(6, parts.size())));
        }
        return new EndpointImpl(protocol, address, routes, routingId, blessings, isMountTable, isLeaf);
    }

    EndpointImpl(String protocol, String address, List<String> routes, RoutingId routingId,
                 List<String> blessingNames, boolean isMountTable, boolean isLeaf) {
        this.protocol = protocol;
        this.address = address;
        this.routes = ImmutableList.copyOf(routes);
        this.routingId = routingId;
        this.blessingNames = ImmutableList.copyOf(blessingNames);
        this.isMountTable = isMountTable;
        this.isLeaf = isLeaf;
    }

    @Override
    public String name() {
        return NamingUtil.joinAddressName(toString(), "");
    }

    @Override
    public RoutingId routingId() {
        return routingId;
    }

    @Override
    public List<String> routes() {
        return routes;
    }

    @Override
    public NetworkAddress address() {
        return new NetworkAddress(protocol, address);
    }

    @Override
    public boolean servesMountTable() {
        return isMountTable;
    }

    @Override
    public boolean isLeaf() {
        return isLeaf;
    }

    @Override
    public List<String> blessingNames() {
        return blessingNames;
    }

    private List<String> escapedRoutes() {
        int len = routes.size();
        List<String> escaped = new ArrayList<>(len);
        for (int i = 0; i < len; i++) {
            escaped.add(escapeString(routes.get(i)));
        }
        return escaped;
    }

    private static List<String> unescapeRoutes(List<String> s) {
        int len = s.size();
        List<String> unescaped = new ArrayList<>(len);
        for (int i = 0; i < len; i++) {
            unescaped.add(unescapeString(s.get(i)));
        }
        return unescaped;
    }

    private String escapedAddress() {
        return escapeString(address);
    }

    private static String unescapeAddress(String address) {
        return unescapeString(address);
    }

    private static String escapeString(String s) {
        CharMatcher matcher = CharMatcher.anyOf("%@");
        int count = matcher.countIn(s);
        if (count == 0) {
            return s;
        }

        char[] escaped = new char[s.length() + 2 * count];
        for (int i = 0; i < s.length(); ) {
            char x = s.charAt(i);
            if (x == '%') {
                escaped[i++] = '%';
                escaped[i++] = '2';
                escaped[i++] = '5';
            } else if (x == '@') {
                escaped[i++] = '%';
                escaped[i++] = '4';
                escaped[i++] = '0';
            } else {
                escaped[i++] = x;
            }
        }
        return new String(escaped);
    }

    private static int digit(char input) {
        int result = Character.digit(input, 16);
        if (result == -1) {
            throw new IllegalArgumentException("invalid hex digit " + input);
        }
        return result;
    }

    private static String unescapeString(String s) {
        if (s.contains("%")) {
            return s;
        }

        int slen = s.length();
        StringBuilder unescaped = new StringBuilder();
        for (int i = 0; i < slen; ) {
            char x = s.charAt(i);
            if (x == '%') {
                char newChar = (char) ((digit(s.charAt(i + 1)) << 4) |
                        (digit(s.charAt(i + 2))));
                unescaped.append(newChar);
                i += 3;
            } else {
                unescaped.append(x);
                i++;
            }
        }
        return unescaped.toString();
    }

    @Override
    public String toString() {
        char mt = 's';
        if (isLeaf) {
            mt = 'l';
        } else if (isMountTable) {
            mt = 'm';
        }
        String blessings = Joiner.on(',').join(blessingNames);
        String routeString = Joiner.on(',').join(escapedRoutes());
        return String.format("@6@%s@%s@%s@%s@%s@%s@@", protocol, escapedAddress(),
            routeString, routingId, mt, blessings);
    }

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

        EndpointImpl endpoint = (EndpointImpl) o;

        if (isMountTable != endpoint.isMountTable) {
            return false;
        }
        if (isLeaf != endpoint.isLeaf) {
            return false;
        }
        if (!protocol.equals(endpoint.protocol)) {
            return false;
        }
        if (!address.equals(endpoint.address)) {
            return false;
        }
        if (!routes.equals(endpoint.routes)) {
            return false;
        }
        if (!routingId.equals(endpoint.routingId)) {
            return false;
        }
        return blessingNames.equals(endpoint.blessingNames);
    }

    @Override
    public int hashCode() {
        return Objects.hash(protocol, address, routes, routingId, blessingNames, isMountTable, isLeaf);
    }
}
