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

import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.speech.srec.WaveHeader;
import android.text.format.DateFormat;
import android.util.Config;
import android.util.Log;

import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileFilter;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * This class logs the inputs and results of a recognition session to
 * the files listed below, which reside in
 * /data/data/com.android.voicedialer/app_logdir.
 * The files have the date encoded in the  name so that they will sort in
 * time order.  The newest RecognizerLogger.MAX_FILES are kept,
 * and the rest deleted to limit space used in the file system.
 * <ul>
 * <li> datename.wav - what the microphone heard.
 * <li> datename.log - contact list, results, errors, etc.
 * </ul>
 */
public class RecognizerLogger {

    private static final String TAG = "RecognizerLogger";
    
    private static final String LOGDIR = "logdir";
    private static final String ENABLED = "enabled";
    
    private static final int MAX_FILES = 20;
    
    private final String mDatedPath;
    private final BufferedWriter mWriter;
    
    /**
     * Determine if logging is enabled.  If the
     * @param context needed to reference the logging directory.
     * @return true if logging is enabled, determined by the 'enabled' file.
     */
    public static boolean isEnabled(Context context) {
        File dir = context.getDir(LOGDIR, 0);
        File enabled = new File(dir, ENABLED);
        return enabled.exists();
    }
    
    /**
     * Enable logging.
     * @param context needed to reference the logging directory.
     */
    public static void enable(Context context) {
        try {
            File dir = context.getDir(LOGDIR, 0);
            File enabled = new File(dir, ENABLED);
            enabled.createNewFile();
        }
        catch (IOException e) {
            Log.e(TAG, "enableLogging " + e);
        }
    }
    
    /**
     * Disable logging.
     * @param context needed to reference the logging directory.
     */
    public static void disable(Context context) {
        try {
            File dir = context.getDir(LOGDIR, 0);
            File enabled = new File(dir, ENABLED);
            enabled.delete();
        }
        catch (SecurityException e) {
            Log.e(TAG, "disableLogging " + e);
        }
    }

    /**
     * Constructor
     * @param dataDir directory to contain the log files.
     */
    public RecognizerLogger(Context context) throws IOException {
        if (Config.LOGD) Log.d(TAG, "RecognizerLogger");
        
        // generate new root filename
        File dir = context.getDir(LOGDIR, 0);
        mDatedPath = dir.toString() + File.separator + "log_" +
                DateFormat.format("yyyy_MM_dd_kk_mm_ss",
                        System.currentTimeMillis());
        
        // delete oldest files
        deleteOldest(".wav");
        deleteOldest(".log");
        
        // generate new text output log file
        mWriter = new BufferedWriter(new FileWriter(mDatedPath + ".log"), 8192);
        mWriter.write(Build.FINGERPRINT);
        mWriter.newLine();
    }
    
    /**
     * Write a line into the text log file.
     */
    public void logLine(String msg) {
        try {
            mWriter.write(msg);
            mWriter.newLine();
        }
        catch (IOException e) {
            Log.e(TAG, "logLine exception: " + e);
        }
    }
    
    /**
     * Write a header for the NBest lines into the text log file.
     */
    public void logNbestHeader() {
        logLine("Nbest *****************");
    }
    
    /**
     * Write the list of contacts into the text log file.
     * @param contacts
     */
    public void logContacts(List<VoiceContact> contacts) {
        logLine("Contacts *****************");
        for (VoiceContact vc : contacts) logLine(vc.toString());
        try {
            mWriter.flush();
        }
        catch (IOException e) {
            Log.e(TAG, "logContacts exception: " + e);
        }
    }
    
    /**
     * Write a list of Intents into the text log file.
     * @param intents
     */
    public void logIntents(ArrayList<Intent> intents) {
        logLine("Intents *********************");
        StringBuffer sb = new StringBuffer();
        for (Intent intent : intents) {
            logLine(intent.toString() + " " + RecognizerEngine.SENTENCE_EXTRA + "=" +
                    intent.getStringExtra(RecognizerEngine.SENTENCE_EXTRA));
        }
        try {
            mWriter.flush();
        }
        catch (IOException e) {
            Log.e(TAG, "logIntents exception: " + e);
        }
    }
    
    /**
     * Close the text log file.
     * @throws IOException
     */
    public void close() throws IOException {
        mWriter.close();
    }

    /**
     * Delete oldest files with a given suffix, if more than MAX_FILES.
     * @param suffix delete oldest files with this suffix.
     */
    private void deleteOldest(final String suffix) {
        FileFilter ff = new FileFilter() {
            public boolean accept(File f) {
                String name = f.getName();
                return name.startsWith("log_") && name.endsWith(suffix);
            }
        };
        File[] files = (new File(mDatedPath)).getParentFile().listFiles(ff);
        Arrays.sort(files);

        for (int i = 0; i < files.length - MAX_FILES; i++) {
            files[i].delete();            
        }
    }

    /**
     * InputStream wrapper which will log the contents to a WAV file.
     * @param inputStream
     * @param sampleRate
     * @return
     */
    public InputStream logInputStream(final InputStream inputStream, final int sampleRate) {
        final ByteArrayOutputStream baos = new ByteArrayOutputStream(sampleRate * 2 * 20);
        
        return new InputStream() {

            public int available() throws IOException {
                return inputStream.available();
            }

            public int read(byte[] b, int offset, int length) throws IOException {
                int rtn = inputStream.read(b, offset, length);
                if (rtn > 0) baos.write(b, offset, rtn);
                return rtn;
            }

            public int read(byte[] b) throws IOException {
                int rtn = inputStream.read(b);
                if (rtn > 0) baos.write(b, 0, rtn);
                return rtn;
            }

            public int read() throws IOException {
                int rtn = inputStream.read();
                if (rtn > 0) baos.write(rtn);
                return rtn;
            }

            public long skip(long n) throws IOException {
                throw new UnsupportedOperationException();
            }

            public void close() throws IOException {
                try {
                    OutputStream out = new FileOutputStream(mDatedPath + ".wav");
                    try {
                        byte[] pcm = baos.toByteArray();
                        WaveHeader hdr = new WaveHeader(WaveHeader.FORMAT_PCM,
                                (short)1, sampleRate, (short)16, pcm.length);
                        hdr.write(out);
                        out.write(pcm);
                    }
                    finally {
                        out.close();
                    }
                }
                finally {
                    inputStream.close();
                    baos.close();
                }
            }
        };
    }

}
