// 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.syncbase.v23.services.syncbase.util;

import com.google.common.base.Charsets;

import java.io.EOFException;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.text.Collator;
import java.util.ArrayList;
import java.util.Collections;

import io.v.impl.google.naming.NamingUtil;
import io.v.v23.InputChannel;
import io.v.v23.V;
import io.v.v23.context.VContext;
import io.v.v23.namespace.Namespace;
import io.v.v23.naming.GlobReply;
import io.v.v23.verror.VException;

/**
 * Various NoSQL utility methods.
 */
public class Util {
    /**
     * Returns the start of the row range for the given prefix.
     */
    public static String prefixRangeStart(String prefix) {
        return prefix;
    }

    /**
     * Returns the limit of the row range for the given prefix.
     */
    public static String prefixRangeLimit(String prefix) {
        // We convert a string to a byte[] array, which can be thought of as a base-256
        // number.  The code below effectively adds 1 to this number, then chops off any
        // trailing 0x00 bytes. If the input string consists entirely of 0xFF, an empty string
        // will be returned.
        try {
            byte[] bytes = prefix.getBytes("ISO8859-1");
            int last = bytes.length - 1;
            for (; last >= 0 && bytes[last] == (byte) 0xFF; --last);
            if (last < 0) {
                return "";
            }
            bytes[last] += 1;
            return new String(bytes, 0, last + 1, "ISO8859-1");
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException("JVM must support ISO8859-1 char encoding", e);
        }
    }

    /**
     * Performs {@link Namespace#glob Namespace.glob("name/*")} and returns a
     * sorted list of results.
     *
     * @param  ctx        Vanadium context
     * @param  globName   name used for globbing
     * @return            a sorted list of results of
     *                    {@link Namespace#glob Namespace.glob("name/*")}
     * @throws VException if a glob error occurred
     */
    public static String[] list(VContext ctx, String globName) throws VException {
        Namespace n = V.getNamespace(ctx);
        InputChannel<GlobReply> chan = n.glob(ctx, NamingUtil.join(globName, "*"));
        ArrayList<String> names = new ArrayList<String>();
        try {
            for (GlobReply reply : chan) {
                if (reply instanceof GlobReply.Entry) {
                    String fullName = ((GlobReply.Entry) reply).getName();
                    // NOTE(nlacasse): The names that come back from Glob are all
                    // rooted.  We only want the last part of the name, so we must chop
                    // off everything before the final '/'.  Since endpoints can
                    // themselves contain slashes, we have to remove the endpoint from
                    // the name first.
                    String name = NamingUtil.splitAddressName(fullName).get(1);
                    int idx = name.lastIndexOf('/');
                    if (idx != -1) {
                        name = name.substring(idx + 1, name.length());
                    }
                    names.add(name);
                } else if (reply instanceof GlobReply.Error) {
                    throw ((GlobReply.Error) reply).getElem().getError();
                } else if (reply == null) {
                    throw new VException("null glob() reply");
                } else {
                    throw new VException("Unrecognized glob() reply type: " + reply.getClass());
                }
            }
        } catch (RuntimeException e) {  // error during iteration
            throw (VException) e.getCause();
        }
        Collections.sort(names, Collator.getInstance());
        return names.toArray(new String[names.size()]);
    }

    /**
     * Returns the UTF-8 encoding of the provided string.
     */
    public static byte[] getBytes(String s) {
        if (s == null) {
            s = "";
        }
        return s.getBytes(Charsets.UTF_8);
    }

    /**
     * Returns the UTF-8 decoded string.
     */
    public static String getString(byte[] bytes) {
        return new String(bytes, Charsets.UTF_8);
    }

    private Util() {}
}
