// 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 java.io.ByteArrayOutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

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

/**
 * Utilities for dealing with Vanadium names.
 */
public class NamingUtil {
    /**
     * Takes an object name and returns the server address and the name relative to the server.
     * <p>
     * The name parameter may be a rooted name or a relative name; an empty string
     * address is returned for the latter case.
     * <p>
     * The returned address may be in endpoint format or {@code host:port} format.
     * <p>
     * The returned list is guaranteed to contain exactly two entries: the server address and
     * the name relative to the server.
     *
     * @param  name name from which the server address and relative name are extracted
     * @return      a list containing exactly two entries: the server address and
     *              the name relative to the server
     */
    public static List<String> splitAddressName(String name) {
        name = clean(name);
        if (!isRooted(name)) {
            return ImmutableList.of("", name);
        }
        name = name.substring(1, name.length()); // trim the beginning "/"
        if (name.isEmpty()) {
            return ImmutableList.of("", "");
        }
        // Could have used regular expressions, but that makes this function
        // 10x slower as per the benchmark.
        if (name.startsWith("@")) { // <endpoint>/<suffix>
            List<String> parts = splitInTwo(name, "@@/");
            String addr = parts.get(0), suffix = parts.get(1);
            if (!suffix.isEmpty()) { // The trailing "@@" was stripped, restore it
                addr += "@@";
            }
            return ImmutableList.of(addr, suffix);
        }
        if (name.startsWith("(")) { // (blessing)@host:[port]/suffix
            String tmp = splitInTwo(name, ")@").get(1);
            String suffix = splitInTwo(tmp, "/").get(1);
            String addr = trimSuffix(name, "/" + suffix);
            if (addr.endsWith("/" + suffix)) {
                addr = addr.substring(0, addr.length() - suffix.length() - 1);
            }
            return ImmutableList.of(addr, suffix);
        }
        // host:[port]/suffix
        List<String> parts = splitInTwo(name, "/");
        return ImmutableList.of(parts.get(0), parts.get(1));
    }

    private static List<String> splitInTwo(String str, String separator) {
       Iterator<String> iter = Splitter.on(separator).limit(2).split(str).iterator();
       return ImmutableList.of(
               iter.hasNext() ? iter.next() : "", iter.hasNext() ? iter.next() : "");
    }

    /**
     * Takes an address and a relative name and returns a rooted or relative name.
     * <p>
     * If a valid address is supplied then the returned name will always be a rooted name (i.e.
     * starting with {@code /}), otherwise it may be relative. {@code address} should not start
     * with a {@code /} and if it does, that prefix will be stripped.
     */
    public static String joinAddressName(String address, String name) {
        address = CharMatcher.is('/').trimLeadingFrom(address);
        if (address.isEmpty()) {
            return clean(name);
        }
        if (name.isEmpty()) {
            return clean("/" + address);
        }
        return clean("/" + address + "/" + name);
    }

    /**
     * Takes a variable number of name fragments and concatenates them together using {@code '/'}.
     * <p>
     * The returned name is cleaned of multiple adjacent {@code '/'}s.
     *
     * @param  names name fragments to be concatenated
     * @return       the concatenated (and cleaned) name
     */
    public static String join(String... names) {
        Iterator<String> iter = Arrays.asList(names).iterator();
        for (int i = 0; i < names.length && names[i].isEmpty(); ++i, iter.next());
        return clean(Joiner.on("/").join(iter));
    }

    /**
     * Splits the given name into fragments using {@code '/'} as the separator.
     * <p>
     * The returned list is cleaned of empty strings.
     */
    public static List<String> split(String name) {
        return Splitter.on("/").omitEmptyStrings().splitToList(name);
    }

    /**
     * Removes the suffix (and any connecting {@code /}) from the name.
     */
    public static String trimSuffix(String name, String suffix) {
        name = clean(name);
        suffix = clean(suffix);

        // Easy cases first.
        if (name.equals(suffix)) {
            return "";
        }
        if (suffix.length() >= name.length()) {
            return name;
        }

        // A suffix starting with a slash cannot be a partial match.
        if (suffix.startsWith("/")) {
            return name;
        }
        // At this point suffix is guaranteed not to start with a '/' and
        // suffix is shorter than name.
        if (name.endsWith(suffix)) {
            String prefix = name.substring(0, name.length() - suffix.length());
            if (prefix.endsWith("/")) {
                if (prefix.length() == 1) {
                    return name;
                }
                return prefix.substring(0, prefix.length() - 1);
            }
            return prefix;
        }
        return name;
    }

    /**
     * Reduces multiple adjacent slashes to a single slash and removes any trailing slash.
     */
    public static String clean(String name) {
        CharMatcher slashMatcher = CharMatcher.is('/');
        name = slashMatcher.collapseFrom(name, '/');
        if ("/".equals(name)) {
            return name;
        }
        return slashMatcher.trimTrailingFrom(name);
    }

    /**
     * Returns {@code true} iff the provided name is rooted.
     * <p>
     * A rooted name is one that starts with a single {@code /} followed by
     * a non-{@code /}.
     * <p>
     * {@code /} on its own is considered rooted.
     */
    public static boolean isRooted(String name) {
        return name.startsWith("/");
    }


    /**
     * Returns a string representable as a name element by escaping {@code /}.
     *
     * @param name Name to encode.
     * @return Encoded name.
     */
    public static String encodeAsNameElement(String name) {
        return escape(name, new char[]{'/'});
    }

    /**
     * Decodes an encoded name element.
     * <p>
     * Note that this is more than the inverse of {@link NamingUtil#encodeAsNameElement} since it
     * can handle more hex encodings than {@code /} and {@code %}.
     * This is intentional since we'll most likely want to add other letters to the set to be encoded.
     *
     * @param name Name to decode.
     * @return Decoded name.
     * @throws IllegalArgumentException if {@code name} is truncated or malformed.
     */
    public static String decodeFromNameElement(String name) {
        return unescape(name);
    }

    private static final String hexDigits = "0123456789ABCDEF";

    /**
     * Encodes a string replacing the characters in {@code special} and {@code %} with a {@code %<hex>} escape.
     *
     * @param text Text to escape.
     * @param special Collection of special characters to escape in {@code text}.
     * @return Encoded text.
     */
    public static String escape(String text, char[] special) {
        /*
         * Note that this function is a modified version of Android's URLEncoder in
         * Android SDK java/net/URLEncoder.java (https://goo.gl/61z5ZV).
         * The biggest difference is that, unlike URLEncoder, our code only encodes characters
         * in {@code special} rather than all non-ASCII characters.
         * We also do not convert space to +.
         */
        String specialStr = new String(special) + '%';

        // Avoid copying the string if it does not have any of the special characters.
        boolean hasSpecial = false;
        for (int i = 0; i < text.length(); i++) {
            char ch = text.charAt(i);
            if (specialStr.indexOf(ch) >= 0) {
                hasSpecial = true;
                break;
            }
        }

        if (!hasSpecial) {
            return text;
        }

        StringBuffer buf = new StringBuffer();
        for (int i = 0; i < text.length(); i++) {
            char ch = text.charAt(i);
            if (specialStr.indexOf(ch) < 0) {
                buf.append(ch);
            } else {
                byte[] bytes = new String(new char[] { ch }).getBytes();
                for (int j = 0; j < bytes.length; j++) {
                    buf.append('%');
                    buf.append(hexDigits.charAt((bytes[j] & 0xf0) >> 4));
                    buf.append(hexDigits.charAt(bytes[j] & 0xf));
                }
            }
        }
        return buf.toString();
    }

    /**
     * Decodes {@code}%<hex>} encodings in a string into the relevant character.
     *
     * @param text
     * @return Decoded text.
     * @throws IllegalArgumentException if the {@code text} is trucated or malformed.
     */
    public static String unescape(String text) {
        /*
         * Note that this function is a slightly modified version of Android's URLDecoder in
         * Android SDK java/net/URLDecoder.java (https://goo.gl/TFrx7E).
         * The biggest difference is that, unlike URLDecoder, our code does not convert + to space.
         * We also avoid string copying if text does not encoded to start with.
         */

        // Avoid string copying if text is not encoded to start with.
        if (text.indexOf('%') < 0){
            return text;
        }

        StringBuffer result = new StringBuffer(text.length());
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        for (int i = 0; i < text.length();) {
            char c = text.charAt(i);
            if (c == '%') {
                out.reset();
                do {
                    if (i + 2 >= text.length()) {
                        throw new IllegalArgumentException("Truncated or malformed encoded string");
                    }
                    int d1 = Character.digit(text.charAt(i + 1), 16);
                    int d2 = Character.digit(text.charAt(i + 2), 16);
                    if (d1 == -1 || d2 == -1) {
                        throw new IllegalArgumentException("Truncated or malformed encoded string");
                    }
                    out.write((byte) ((d1 << 4) + d2));
                    i += 3;
                } while (i < text.length() && text.charAt(i) == '%');
                result.append(out.toString());
                continue;
            } else {
                result.append(c);
            }
            i++;
        }
        return result.toString();

    }

    private NamingUtil() {}
}
