/*
 * Copyright (C) 2007 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.ddmlib;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;

/**
 * Base implementation of {@link IShellOutputReceiver}, that takes the raw data coming from the
 * socket, and convert it into {@link String} objects.
 * <p/>Additionally, it splits the string by lines.
 * <p/>Classes extending it must implement {@link #processNewLines(String[])} which receives
 * new parsed lines as they become available.
 */
public abstract class MultiLineReceiver implements IShellOutputReceiver {

    private boolean mTrimLines = true;

    /** unfinished message line, stored for next packet */
    private String mUnfinishedLine = null;

    private final ArrayList<String> mArray = new ArrayList<String>();

    /**
     * Set the trim lines flag.
     * @param trim hether the lines are trimmed, or not.
     */
    public void setTrimLine(boolean trim) {
        mTrimLines = trim;
    }

    /* (non-Javadoc)
     * @see com.android.ddmlib.adb.IShellOutputReceiver#addOutput(
     *      byte[], int, int)
     */
    @Override
    public final void addOutput(byte[] data, int offset, int length) {
        if (isCancelled() == false) {
            String s = null;
            try {
                s = new String(data, offset, length, "UTF-8"); //$NON-NLS-1$
            } catch (UnsupportedEncodingException e) {
                // normal encoding didn't work, try the default one
                s = new String(data, offset,length);
            }

            // ok we've got a string
            if (s != null) {
                // if we had an unfinished line we add it.
                if (mUnfinishedLine != null) {
                    s = mUnfinishedLine + s;
                    mUnfinishedLine = null;
                }

                // now we split the lines
                mArray.clear();
                int start = 0;
                do {
                    int index = s.indexOf("\r\n", start); //$NON-NLS-1$

                    // if \r\n was not found, this is an unfinished line
                    // and we store it to be processed for the next packet
                    if (index == -1) {
                        mUnfinishedLine = s.substring(start);
                        break;
                    }

                    // so we found a \r\n;
                    // extract the line
                    String line = s.substring(start, index);
                    if (mTrimLines) {
                        line = line.trim();
                    }
                    mArray.add(line);

                    // move start to after the \r\n we found
                    start = index + 2;
                } while (true);

                if (mArray.size() > 0) {
                    // at this point we've split all the lines.
                    // make the array
                    String[] lines = mArray.toArray(new String[mArray.size()]);

                    // send it for final processing
                    processNewLines(lines);
                }
            }
        }
    }

    /* (non-Javadoc)
     * @see com.android.ddmlib.adb.IShellOutputReceiver#flush()
     */
    @Override
    public final void flush() {
        if (mUnfinishedLine != null) {
            processNewLines(new String[] { mUnfinishedLine });
        }

        done();
    }

    /**
     * Terminates the process. This is called after the last lines have been through
     * {@link #processNewLines(String[])}.
     */
    public void done() {
        // do nothing.
    }

    /**
     * Called when new lines are being received by the remote process.
     * <p/>It is guaranteed that the lines are complete when they are given to this method.
     * @param lines The array containing the new lines.
     */
    public abstract void processNewLines(String[] lines);
}
