/*
 * 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.util.Log;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;

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

    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 final File mFileName;
    private int mSampleRateInHz;
    private int mAudioFormat;
    private int mChannelCount;
    private RandomAccessFile mFile;
    private boolean mStopped = false;
    private boolean mDone = false;

    FileSynthesisRequest(String text, File fileName) {
        super(text);
        mFileName = fileName;
    }

    @Override
    void stop() {
        synchronized (mStateLock) {
            mStopped = true;
            cleanUp();
        }
    }

    /**
     * Must be called while holding the monitor on {@link #mStateLock}.
     */
    private void cleanUp() {
        closeFile();
        if (mFile != null) {
            mFileName.delete();
        }
    }

    /**
     * Must be called while holding the monitor on {@link #mStateLock}.
     */
    private void closeFile() {
        try {
            if (mFile != null) {
                mFile.close();
                mFile = null;
            }
        } catch (IOException ex) {
            Log.e(TAG, "Failed to close " + mFileName + ": " + ex);
        }
    }

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

    @Override
    boolean isDone() {
        return mDone;
    }

    @Override
    public int start(int sampleRateInHz, int audioFormat, int channelCount) {
        if (DBG) {
            Log.d(TAG, "FileSynthesisRequest.start(" + sampleRateInHz + "," + audioFormat
                    + "," + channelCount + ")");
        }
        synchronized (mStateLock) {
            if (mStopped) {
                if (DBG) Log.d(TAG, "Request has been aborted.");
                return TextToSpeech.ERROR;
            }
            if (mFile != null) {
                cleanUp();
                throw new IllegalArgumentException("FileSynthesisRequest.start() called twice");
            }
            mSampleRateInHz = sampleRateInHz;
            mAudioFormat = audioFormat;
            mChannelCount = channelCount;
            try {
                mFile = new RandomAccessFile(mFileName, "rw");
                // Reserve space for WAV header
                mFile.write(new byte[WAV_HEADER_LENGTH]);
                return TextToSpeech.SUCCESS;
            } catch (IOException ex) {
                Log.e(TAG, "Failed to open " + mFileName + ": " + ex);
                cleanUp();
                return TextToSpeech.ERROR;
            }
        }
    }

    @Override
    public int audioAvailable(byte[] buffer, int offset, int length) {
        if (DBG) {
            Log.d(TAG, "FileSynthesisRequest.audioAvailable(" + buffer + "," + offset
                    + "," + length + ")");
        }
        synchronized (mStateLock) {
            if (mStopped) {
                if (DBG) Log.d(TAG, "Request has been aborted.");
                return TextToSpeech.ERROR;
            }
            if (mFile == null) {
                Log.e(TAG, "File not open");
                return TextToSpeech.ERROR;
            }
            try {
                mFile.write(buffer, offset, length);
                return TextToSpeech.SUCCESS;
            } catch (IOException ex) {
                Log.e(TAG, "Failed to write to " + mFileName + ": " + ex);
                cleanUp();
                return TextToSpeech.ERROR;
            }
        }
    }

    @Override
    public int done() {
        if (DBG) Log.d(TAG, "FileSynthesisRequest.done()");
        synchronized (mStateLock) {
            if (mStopped) {
                if (DBG) Log.d(TAG, "Request has been aborted.");
                return TextToSpeech.ERROR;
            }
            if (mFile == null) {
                Log.e(TAG, "File not open");
                return TextToSpeech.ERROR;
            }
            try {
                // Write WAV header at start of file
                mFile.seek(0);
                int dataLength = (int) (mFile.length() - WAV_HEADER_LENGTH);
                mFile.write(
                        makeWavHeader(mSampleRateInHz, mAudioFormat, mChannelCount, dataLength));
                closeFile();
                mDone = true;
                return TextToSpeech.SUCCESS;
            } catch (IOException ex) {
                Log.e(TAG, "Failed to write to " + mFileName + ": " + ex);
                cleanUp();
                return TextToSpeech.ERROR;
            }
        }
    }

    @Override
    public void error() {
        if (DBG) Log.d(TAG, "FileSynthesisRequest.error()");
        synchronized (mStateLock) {
            cleanUp();
        }
    }

    @Override
    public int completeAudioAvailable(int sampleRateInHz, int audioFormat, int channelCount,
            byte[] buffer, int offset, int length) {
        synchronized (mStateLock) {
            if (mStopped) {
                if (DBG) Log.d(TAG, "Request has been aborted.");
                return TextToSpeech.ERROR;
            }
        }
        FileOutputStream out = null;
        try {
            out = new FileOutputStream(mFileName);
            out.write(makeWavHeader(sampleRateInHz, audioFormat, channelCount, length));
            out.write(buffer, offset, length);
            mDone = true;
            return TextToSpeech.SUCCESS;
        } catch (IOException ex) {
            Log.e(TAG, "Failed to write to " + mFileName + ": " + ex);
            mFileName.delete();
            return TextToSpeech.ERROR;
        } finally {
            try {
                if (out != null) {
                    out.close();
                }
            } catch (IOException ex) {
                Log.e(TAG, "Failed to close " + mFileName + ": " + ex);
            }
        }
    }

    private byte[] 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);

        return headerBuf;
    }

}
