package doglet.text;

import nova.Machine;
import nova.Store;
import nova.runtime;
import nova.special;

import java.util.HashMap;
import java.util.Map;

/**
 * Warranty & Liability
 * To the extent permitted by applicable law and unless explicitly
 * otherwise agreed upon, XLOG Technologies AG makes no warranties
 * regarding the provided information. XLOG Technologies AG assumes
 * no liability that any problems might be solved with the information
 * provided by XLOG Technologies AG.
 *
 * Rights & License
 * All industrial property rights regarding the information - copyright
 * and patent rights in particular - are the sole property of XLOG
 * Technologies AG. If the company was not the originator of some
 * excerpts, XLOG Technologies AG has at least obtained the right to
 * reproduce, change and translate the information.
 *
 * Reproduction is restricted to the whole unaltered document. Reproduction
 * of the information is only allowed for non-commercial uses. Selling,
 * giving away or letting of the execution of the library is prohibited.
 * The library can be distributed as part of your applications and libraries
 * for execution provided this comment remains unchanged.
 *
 * Restrictions
 * Only to be distributed with programs that add significant and primary
 * functionality to the library. Not to be distributed with additional
 * software intended to replace any components of the library.
 *
 * Trademarks
 * Jekejeke is a registered trademark of XLOG Technologies AG.
 */
public final class auxlib {

    /******************************************************************/
    /* open_input_atom_stream/2                                       */
    /******************************************************************/

    /**
     * open_input_atom_stream(A, S): internal only
     * The built-in succeeds in S with a new input stream for the atom A.
     */
    private static boolean test_open_input_atom_stream(Object[] args) {
        Object text = Machine.exec_build(args[0]);
        special.check_atom(text);
        runtime.Source src = new runtime.Source();
        src.buf = (String) text;
        return Machine.exec_unify(args[1], src);
    }

    /******************************************************************/
    /* open_output_atom_stream/1 and sys_output_atom_stream_get/2     */
    /******************************************************************/

    /**
     * open_output_atom_stream(S): internal only
     * The built-in succeeds in S with a new output stream.
     */
    private static boolean test_open_output_atom_stream(Object[] args) {
        runtime.Sink dst = new runtime.Sink();
        dst.data = new StringBuilder();
        dst.send = auxlib::mem_send;
        return Machine.exec_unify(args[0], dst);
    }

    private static Object mem_send(Object data, String buf) {
        ((StringBuilder) data).append(buf);
        return data;
    }

    /**
     * sys_output_atom_stream_get(S, A): internal only
     * The built-in succeeds in A with the content of the output stream S.
     */
    private static boolean test_sys_output_atom_stream_get(Object[] args) {
        Object writer = Machine.exec_build(args[0]);
        runtime.check_sink(writer);
        String res = ((StringBuilder) ((runtime.Sink) writer).data).toString();
        return Machine.exec_unify(args[1], res);
    }

    /******************************************************************/
    /* Aux Lib Init                                                   */
    /******************************************************************/

    public static void main() {
        Store.set("open_input_atom_stream", 2, special.make_check(auxlib::test_open_input_atom_stream));
        Store.set("open_output_atom_stream", 1, special.make_check(auxlib::test_open_output_atom_stream));
        Store.set("sys_output_atom_stream_get", 2, special.make_check(auxlib::test_sys_output_atom_stream_get));
    }

}
