/* UtilLib - Copyright (c) 2020 Vincent Calame - Exemole
 * Logiciel libre donné sous triple licence :
 * 1) selon les termes de la CeCILL V2
 * 2) selon les termes de l’EUPL V.1.1
 * 3) selon les termes de la GNU GPLv3
 * Voir le fichier licences.txt
 */


package net.mapeadores.util.uml;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;
import net.mapeadores.util.exceptions.ShouldNotOccurException;
import net.mapeadores.util.text.StringUtils;


/**
 *
 * @author Vincent Calame
 */
public final class PumlUtils {

    public final static String PLANTUML_URL = "http://www.plantuml.com/plantuml/";

    private PumlUtils() {

    }

    public static void start(Appendable appendable) throws IOException {
        appendable.append("@startuml\n\n");
    }

    public static void end(Appendable appendable) throws IOException {
        appendable.append("\n@enduml");
    }

    public static void startTogether(Appendable appendable) throws IOException {
        appendable.append("together {\n");
    }

    public static void endTogether(Appendable appendable) throws IOException {
        appendable.append("}\n\n");
    }

    public static void hideEmpties(Appendable appendable) throws IOException {
        appendable.append("hide empty members\n");
        appendable.append("hide empty methods\n\n");
    }

    public static void title(Appendable appendable, String title) throws IOException {
        appendable.append("title ");
        appendable.append(title);
        appendable.append("\n\n");
    }

    public static void orthoLineType(Appendable appendable) throws IOException {
        appendable.append("skinparam linetype ortho\n\n");
    }

    public static String encode(String puml) {
        AsciiEncoder asciiEncoder = new AsciiEncoder();
        CompressionZlib compressionZlib = new CompressionZlib();
        String[] tokens = StringUtils.getLineTokens(puml, StringUtils.EMPTY_EXCLUDE);
        StringBuilder buf = new StringBuilder();
        for (String token : tokens) {
            if (buf.length() > 0) {
                buf.append('\n');
            }
            buf.append(token);
        }
        try {
            final byte[] compressedData = compressionZlib.compress(buf.toString().getBytes("UTF-8"));
            return asciiEncoder.encode(compressedData);
        } catch (IOException ioe) {
            throw new ShouldNotOccurException(ioe);
        }
    }

    public static void download(String encodedPuml, String extension, OutputStream outputStream) throws IOException {
        URL url = new URL(PLANTUML_URL + extension + "/" + encodedPuml);
        URLConnection connection = url.openConnection();
        connection.addRequestProperty("User-Agent", "Java");
        try (InputStream is = connection.getInputStream()) {
            byte[] buffer = new byte[1024];
            int size;
            while ((size = is.read(buffer, 0, 1024)) > 0) {
                outputStream.write(buffer, 0, size);
            }
        }
    }


}
