/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package freemarker.template.utility;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.Reader;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.Writer;
import java.util.Map;

import freemarker.template.TemplateTransformModel;

/**
 * <p>Transformer that supports FreeMarker legacy behavior: all newlines appearing
 * within the transformed area will be transformed into the platform's default
 * newline. Unlike the old behavior, however, newlines generated by the data
 * model are also converted. Legacy behavior was to leave newlines in the
 * data model unaltered.</p>
 *
 * <p>Usage:<br>
 * From java:</p>
 * <pre>
 * SimpleHash root = new SimpleHash();
 *
 * root.put( "normalizeNewlines", new freemarker.template.utility.NormalizeNewlines() );
 *
 * ...
 * </pre>
 *
 * <p>From your FreeMarker template:</p>
 * <pre>
 * &lt;transform normalizeNewlines&gt;
 *   &lt;html&gt;
 *   &lt;head&gt;
 *   ...
 *   &lt;p&gt;This template has all newlines normalized to the current platform's
 *   default.&lt;/p&gt;
 *   ...
 *   &lt;/body&gt;
 *   &lt;/html&gt;
 * &lt;/transform&gt;
 * </pre>
 */
public class NormalizeNewlines implements TemplateTransformModel {

    @Override
    public Writer getWriter(final Writer out,
                            final Map args) {
        final StringBuilder buf = new StringBuilder();
        return new Writer() {
            @Override
            public void write(char cbuf[], int off, int len) {
                buf.append(cbuf, off, len);
            }

            @Override
            public void flush() throws IOException {
                out.flush();
            }

            @Override
            public void close() throws IOException {
                StringReader sr = new StringReader(buf.toString());
                StringWriter sw = new StringWriter();
                transform(sr, sw);
                out.write(sw.toString());
            }
        };
    }

    /**
     * Performs newline normalization on FreeMarker output.
     *
     * @param in the input to be transformed
     * @param out the destination of the transformation
     */
    public void transform(Reader in, Writer out) throws IOException {
        BufferedReader br = (in instanceof BufferedReader)
                            ? (BufferedReader) in
                            : new BufferedReader(in);
        PrintWriter pw = (out instanceof PrintWriter)
                         ? (PrintWriter) out
                         : new PrintWriter(out);
        String line = br.readLine();
        if (line != null) {
            if ( line.length() > 0 ) {
                pw.println(line);
            }
        }
        while ((line = br.readLine()) != null) {
            pw.println(line);
        }
    }
}
