/*
 * Copyright (C) 2011 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 android.speech.tts;

import android.media.AudioFormat;
import android.speech.tts.TextToSpeechService.UtteranceProgressDispatcher;
import android.util.Log;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.channels.FileChannel;

/**
 * Speech synthesis request that writes the audio to a WAV file.
 */
class FileSynthesisCallback extends AbstractSynthesisCallback {

    private static final String TAG = "FileSynthesisRequest";
    private static final boolean DBG = false;

    private static final int MAX_AUDIO_BUFFER_SIZE = 8192;

    private static final int WAV_HEADER_LENGTH = 44;
    private static final short WAV_FORMAT_PCM = 0x0001;

    private final Object mStateLock = new Object();

    private int mSampleRateInHz;
    private int mAudioFormat;
    private int mChannelCount;

    private FileChannel mFileChannel;

    private final UtteranceProgressDispatcher mDispatcher;
    private final Object mCallerIdentity;

    private boolean mStarted = false;
    private boolean mDone = false;

    /** Status code of synthesis */
    protected int mStatusCode;

    FileSynthesisCallback(FileChannel fileChannel, UtteranceProgressDispatcher dispatcher,
            Object callerIdentity, boolean clientIsUsingV2) {
        super(clientIsUsingV2);
        mFileChannel = fileChannel;
        mDispatcher = dispatcher;
        mCallerIdentity = callerIdentity;
        mStatusCode = TextToSpeechClient.Status.SUCCESS;
    }

    @Override
    void stop() {
        synchronized (mStateLock) {
            if (mDone) {
                return;
            }
            if (mStatusCode == TextToSpeechClient.Status.STOPPED) {
                return;
            }

            mStatusCode = TextToSpeechClient.Status.STOPPED;
            cleanUp();
            if (mDispatcher != null) {
                mDispatcher.dispatchOnStop();
            }
        }
    }

    /**
     * Must be called while holding the monitor on {@link #mStateLock}.
     */
    private void cleanUp() {
        closeFile();
    }

    /**
     * Must be called while holding the monitor on {@link #mStateLock}.
     */
    private void closeFile() {
        // File will be closed by the SpeechItem in the speech service.
        mFileChannel = null;
    }

    @Override
    public int getMaxBufferSize() {
        return MAX_AUDIO_BUFFER_SIZE;
    }

    @Override
    public int start(int sampleRateInHz, int audioFormat, int channelCount) {
        if (DBG) {
            Log.d(TAG, "FileSynthesisRequest.start(" + sampleRateInHz + "," + audioFormat
                    + "," + channelCount + ")");
        }
        FileChannel fileChannel = null;
        synchronized (mStateLock) {
            if (mStatusCode == TextToSpeechClient.Status.STOPPED) {
                if (DBG) Log.d(TAG, "Request has been aborted.");
                return errorCodeOnStop();
            }
            if (mStatusCode != TextToSpeechClient.Status.SUCCESS) {
                if (DBG) Log.d(TAG, "Error was raised");
                return TextToSpeech.ERROR;
            }
            if (mStarted) {
                Log.e(TAG, "Start called twice");
                return TextToSpeech.ERROR;
            }
            mStarted = true;
            mSampleRateInHz = sampleRateInHz;
            mAudioFormat = audioFormat;
            mChannelCount = channelCount;

            if (mDispatcher != null) {
                mDispatcher.dispatchOnStart();
            }
            fileChannel = mFileChannel;
        }

        try {
            fileChannel.write(ByteBuffer.allocate(WAV_HEADER_LENGTH));
                return TextToSpeech.SUCCESS;
        } catch (IOException ex) {
            Log.e(TAG, "Failed to write wav header to output file descriptor", ex);
            synchronized (mStateLock) {
                cleanUp();
                mStatusCode = TextToSpeechClient.Status.ERROR_OUTPUT;
            }
            return TextToSpeech.ERROR;
        }
    }

    @Override
    public int audioAvailable(byte[] buffer, int offset, int length) {
        if (DBG) {
            Log.d(TAG, "FileSynthesisRequest.audioAvailable(" + buffer + "," + offset
                    + "," + length + ")");
        }
        FileChannel fileChannel = null;
        synchronized (mStateLock) {
            if (mStatusCode == TextToSpeechClient.Status.STOPPED) {
                if (DBG) Log.d(TAG, "Request has been aborted.");
                return errorCodeOnStop();
            }
            if (mStatusCode != TextToSpeechClient.Status.SUCCESS) {
                if (DBG) Log.d(TAG, "Error was raised");
                return TextToSpeech.ERROR;
            }
            if (mFileChannel == null) {
                Log.e(TAG, "File not open");
                mStatusCode = TextToSpeechClient.Status.ERROR_OUTPUT;
                return TextToSpeech.ERROR;
            }
            if (!mStarted) {
                Log.e(TAG, "Start method was not called");
                return TextToSpeech.ERROR;
            }
            fileChannel = mFileChannel;
        }

        try {
            fileChannel.write(ByteBuffer.wrap(buffer,  offset,  length));
            return TextToSpeech.SUCCESS;
        } catch (IOException ex) {
            Log.e(TAG, "Failed to write to output file descriptor", ex);
            synchronized (mStateLock) {
                cleanUp();
                mStatusCode = TextToSpeechClient.Status.ERROR_OUTPUT;
            }
            return TextToSpeech.ERROR;
        }
    }

    @Override
    public int done() {
        if (DBG) Log.d(TAG, "FileSynthesisRequest.done()");
        FileChannel fileChannel = null;

        int sampleRateInHz = 0;
        int audioFormat = 0;
        int channelCount = 0;

        synchronized (mStateLock) {
            if (mDone) {
                Log.w(TAG, "Duplicate call to done()");
                // This is not an error that would prevent synthesis. Hence no
                // setStatusCode is set.
                return TextToSpeech.ERROR;
            }
            if (mStatusCode == TextToSpeechClient.Status.STOPPED) {
                if (DBG) Log.d(TAG, "Request has been aborted.");
                return errorCodeOnStop();
            }
            if (mDispatcher != null && mStatusCode != TextToSpeechClient.Status.SUCCESS &&
                    mStatusCode != TextToSpeechClient.Status.STOPPED) {
                mDispatcher.dispatchOnError(mStatusCode);
                return TextToSpeech.ERROR;
            }
            if (mFileChannel == null) {
                Log.e(TAG, "File not open");
                return TextToSpeech.ERROR;
            }
            mDone = true;
            fileChannel = mFileChannel;
            sampleRateInHz = mSampleRateInHz;
            audioFormat = mAudioFormat;
            channelCount = mChannelCount;
        }

        try {
            // Write WAV header at start of file
            fileChannel.position(0);
            int dataLength = (int) (fileChannel.size() - WAV_HEADER_LENGTH);
            fileChannel.write(
                    makeWavHeader(sampleRateInHz, audioFormat, channelCount, dataLength));

            synchronized (mStateLock) {
                closeFile();
                if (mDispatcher != null) {
                    mDispatcher.dispatchOnSuccess();
                }
                return TextToSpeech.SUCCESS;
            }
        } catch (IOException ex) {
            Log.e(TAG, "Failed to write to output file descriptor", ex);
            synchronized (mStateLock) {
                cleanUp();
            }
            return TextToSpeech.ERROR;
        }
    }

    @Override
    public void error() {
        error(TextToSpeechClient.Status.ERROR_SYNTHESIS);
    }

    @Override
    public void error(int errorCode) {
        if (DBG) Log.d(TAG, "FileSynthesisRequest.error()");
        synchronized (mStateLock) {
            if (mDone) {
                return;
            }
            cleanUp();
            mStatusCode = errorCode;
        }
    }

    @Override
    public boolean hasStarted() {
        synchronized (mStateLock) {
            return mStarted;
        }
    }

    @Override
    public boolean hasFinished() {
        synchronized (mStateLock) {
            return mDone;
        }
    }

    private ByteBuffer makeWavHeader(int sampleRateInHz, int audioFormat, int channelCount,
            int dataLength) {
        // TODO: is AudioFormat.ENCODING_DEFAULT always the same as ENCODING_PCM_16BIT?
        int sampleSizeInBytes = (audioFormat == AudioFormat.ENCODING_PCM_8BIT ? 1 : 2);
        int byteRate = sampleRateInHz * sampleSizeInBytes * channelCount;
        short blockAlign = (short) (sampleSizeInBytes * channelCount);
        short bitsPerSample = (short) (sampleSizeInBytes * 8);

        byte[] headerBuf = new byte[WAV_HEADER_LENGTH];
        ByteBuffer header = ByteBuffer.wrap(headerBuf);
        header.order(ByteOrder.LITTLE_ENDIAN);

        header.put(new byte[]{ 'R', 'I', 'F', 'F' });
        header.putInt(dataLength + WAV_HEADER_LENGTH - 8);  // RIFF chunk size
        header.put(new byte[]{ 'W', 'A', 'V', 'E' });
        header.put(new byte[]{ 'f', 'm', 't', ' ' });
        header.putInt(16);  // size of fmt chunk
        header.putShort(WAV_FORMAT_PCM);
        header.putShort((short) channelCount);
        header.putInt(sampleRateInHz);
        header.putInt(byteRate);
        header.putShort(blockAlign);
        header.putShort(bitsPerSample);
        header.put(new byte[]{ 'd', 'a', 't', 'a' });
        header.putInt(dataLength);
        header.flip();

        return header;
    }

    @Override
    public int fallback() {
        synchronized (mStateLock) {
            if (hasStarted() || hasFinished()) {
                return TextToSpeech.ERROR;
            }

            mDispatcher.dispatchOnFallback();
            mStatusCode = TextToSpeechClient.Status.SUCCESS;
            return TextToSpeechClient.Status.SUCCESS;
        }
    }
}
