// Copyright 2011, 2012 Tony Garnock-Jones <tonygarnockjones@gmail.com>.
//
// This file is part of Hop.
//
// Hop is free software: you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Hop is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
// or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
// License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Hop.  If not, see <http://www.gnu.org/licenses/>.
//
package hop;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;

/**
 */
public class SexpWriter {
    public OutputStream _output;

    public SexpWriter(OutputStream output) {
        _output = output;
    }

    public static void writeSimpleString(OutputStream stream, byte[] buf) throws IOException {
        stream.write(Integer.toString(buf.length).getBytes());
        stream.write(':');
        stream.write(buf);
    }

    public void write(Object x) throws IOException {
        if (x instanceof String) {
            writeSimpleString(_output, ((String) x).getBytes());
            return;
        }
        if (x instanceof byte[]) {
            writeSimpleString(_output, ((byte[]) x));
            return;
        }
        if (x instanceof SexpBytes) {
            ((SexpBytes) x).writeTo(_output);
            return;
        }
        if (x instanceof List) {
            _output.write('(');
            for (Object v : ((List<Object>) x)) {
                write(v);
            }
            _output.write(')');
            return;
        }
        if (x == null) {
            _output.write("0:".getBytes());
            return;
        }
        throw new SexpSyntaxError("Unsupported sexp object type");
    }

    public static void write(OutputStream output, Object x) throws IOException {
        new SexpWriter(output).write(x);
    }

    public static String writeString(Object x) {
        try {
            ByteArrayOutputStream o = new ByteArrayOutputStream();
            write(o, x);
            return new String(o.toByteArray());
        } catch (IOException ioe) {
            return x.toString();
        }
    }
}
