/* Copyright 2010, The Android Open Source Project
 **
 ** Licensed 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 com.android.exchange.utility;

import com.android.email.Utility;

import android.text.TextUtils;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;

/**
 * Class to generate iCalender object (*.ics) per RFC 5545.
 */
public class SimpleIcsWriter {
    private static final int MAX_LINE_LENGTH = 75; // In bytes, excluding CRLF
    private static final int CHAR_MAX_BYTES_IN_UTF8 = 4;  // Used to be 6, but RFC3629 limited it.
    private final ByteArrayOutputStream mOut = new ByteArrayOutputStream();

    public SimpleIcsWriter() {
    }

    /**
     * Low level method to write a line, performing line-folding if necessary.
     */
    /* package for testing */ void writeLine(String string) {
        int numBytes = 0;
        for (byte b : Utility.toUtf8(string)) {
            // Fold it when necessary.
            // To make it simple, we assume all chars are 4 bytes.
            // If not (and usually it's not), we end up wrapping earlier than necessary, but that's
            // completely fine.
            if (numBytes > (MAX_LINE_LENGTH - CHAR_MAX_BYTES_IN_UTF8)
                    && Utility.isFirstUtf8Byte(b)) { // Only wrappable if it's before the first byte
                mOut.write((byte) '\r');
                mOut.write((byte) '\n');
                mOut.write((byte) '\t');
                numBytes = 1; // for TAB
            }
            mOut.write(b);
            numBytes++;
        }
        mOut.write((byte) '\r');
        mOut.write((byte) '\n');
    }

    /**
     * Write a tag with a value.
     */
    public void writeTag(String name, String value) {
        // Belt and suspenders here; don't crash on null value; just return
        if (TextUtils.isEmpty(value)) {
            return;
        }

        // The following properties take a TEXT value, which need to be escaped.
        // (These property names should be all interned, so using equals() should be faster than
        // using a hash table.)

        // TODO make constants for these literals
        if ("CALSCALE".equals(name)
                || "METHOD".equals(name)
                || "PRODID".equals(name)
                || "VERSION".equals(name)
                || "CATEGORIES".equals(name)
                || "CLASS".equals(name)
                || "COMMENT".equals(name)
                || "DESCRIPTION".equals(name)
                || "LOCATION".equals(name)
                || "RESOURCES".equals(name)
                || "STATUS".equals(name)
                || "SUMMARY".equals(name)
                || "TRANSP".equals(name)
                || "TZID".equals(name)
                || "TZNAME".equals(name)
                || "CONTACT".equals(name)
                || "RELATED-TO".equals(name)
                || "UID".equals(name)
                || "ACTION".equals(name)
                || "REQUEST-STATUS".equals(name)
                || "X-LIC-LOCATION".equals(name)
                ) {
            value = escapeTextValue(value);
        }
        writeLine(name + ":" + value);
    }

    /**
     * For debugging
     */
    @Override
    public String toString() {
        return Utility.fromUtf8(getBytes());
    }

    /**
     * @return the entire iCalendar invitation object.
     */
    public byte[] getBytes() {
        try {
            mOut.flush();
        } catch (IOException wonthappen) {
        }
        return mOut.toByteArray();
    }

    /**
     * Quote a param-value string, according to RFC 5545, section 3.1
     */
    public static String quoteParamValue(String paramValue) {
        if (paramValue == null) {
            return null;
        }
        // Wrap with double quotes.
        // The spec doesn't allow putting double-quotes in a param value, so let's use single quotes
        // as a substitute.
        // It's not the smartest implementation.  e.g. we don't have to wrap an empty string with
        // double quotes.  But it works.
        return "\"" + paramValue.replace("\"", "'") + "\"";
    }

    /**
     * Escape a TEXT value per RFC 5545 section 3.3.11
     */
    /* package for testing */ static String escapeTextValue(String s) {
        StringBuilder sb = new StringBuilder(s.length());
        for (int i = 0; i < s.length(); i++) {
            char ch = s.charAt(i);
            if (ch == '\n') {
                sb.append("\\n");
            } else if (ch == '\r') {
                // Remove CR
            } else if (ch == ',' || ch == ';' || ch == '\\') {
                sb.append('\\');
                sb.append(ch);
            } else {
                sb.append(ch);
            }
        }
        return sb.toString();
    }
}
