/*
 * Copyright (C) 2009 ZXing authors
 *
 * 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.google.zxing.client.android.history;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.nio.charset.Charset;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import android.app.Activity;
import android.content.ContentValues;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;
import android.net.Uri;
import android.os.Environment;
import android.preference.PreferenceManager;
import android.util.Log;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.Result;
import com.google.zxing.client.android.Intents;
import com.google.zxing.client.android.PreferencesActivity;
import com.google.zxing.client.android.result.ResultHandler;

/**
 * <p>Manages functionality related to scan history.</p>
 *
 * @author Sean Owen
 */
public final class HistoryManager {

  private static final String TAG = HistoryManager.class.getSimpleName();

  private static final int MAX_ITEMS = 2000;

  private static final String[] COLUMNS = {
      DBHelper.TEXT_COL,
      DBHelper.DISPLAY_COL,
      DBHelper.FORMAT_COL,
      DBHelper.TIMESTAMP_COL,
      DBHelper.DETAILS_COL,
  };

  private static final String[] COUNT_COLUMN = { "COUNT(1)" };

  private static final String[] ID_COL_PROJECTION = { DBHelper.ID_COL };
  private static final String[] ID_DETAIL_COL_PROJECTION = { DBHelper.ID_COL, DBHelper.DETAILS_COL };

  private final Activity activity;
  private final boolean enableHistory;

  public HistoryManager(Activity activity) {
    this.activity = activity;
    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
    enableHistory = prefs.getBoolean(PreferencesActivity.KEY_ENABLE_HISTORY, true);
  }

  public boolean hasHistoryItems() {
    SQLiteOpenHelper helper = new DBHelper(activity);
    SQLiteDatabase db = null;
    Cursor cursor = null;
    try {
      db = helper.getReadableDatabase();
      cursor = db.query(DBHelper.TABLE_NAME, COUNT_COLUMN, null, null, null, null, null);
      cursor.moveToFirst();
      return cursor.getInt(0) > 0;
    } finally {
      close(cursor, db);
    }
  }

  public List<HistoryItem> buildHistoryItems() {
    SQLiteOpenHelper helper = new DBHelper(activity);
    List<HistoryItem> items = new ArrayList<>();
    SQLiteDatabase db = null;
    Cursor cursor = null;
    try {
      db = helper.getReadableDatabase();
      cursor = db.query(DBHelper.TABLE_NAME, COLUMNS, null, null, null, null, DBHelper.TIMESTAMP_COL + " DESC");
      while (cursor.moveToNext()) {
        String text = cursor.getString(0);
        String display = cursor.getString(1);
        String format = cursor.getString(2);
        long timestamp = cursor.getLong(3);
        String details = cursor.getString(4);
        Result result = new Result(text, null, null, BarcodeFormat.valueOf(format), timestamp);
        items.add(new HistoryItem(result, display, details));
      }
    } finally {
      close(cursor, db);
    }
    return items;
  }

  public HistoryItem buildHistoryItem(int number) {
    SQLiteOpenHelper helper = new DBHelper(activity);
    SQLiteDatabase db = null;
    Cursor cursor = null;
    try {
      db = helper.getReadableDatabase();
      cursor = db.query(DBHelper.TABLE_NAME, COLUMNS, null, null, null, null, DBHelper.TIMESTAMP_COL + " DESC");
      cursor.move(number + 1);
      String text = cursor.getString(0);
      String display = cursor.getString(1);
      String format = cursor.getString(2);
      long timestamp = cursor.getLong(3);
      String details = cursor.getString(4);
      Result result = new Result(text, null, null, BarcodeFormat.valueOf(format), timestamp);
      return new HistoryItem(result, display, details);
    } finally {
      close(cursor, db);
    }
  }
  
  public void deleteHistoryItem(int number) {
    SQLiteOpenHelper helper = new DBHelper(activity);
    SQLiteDatabase db = null;
    Cursor cursor = null;
    try {
      db = helper.getWritableDatabase();      
      cursor = db.query(DBHelper.TABLE_NAME,
                        ID_COL_PROJECTION,
                        null, null, null, null,
                        DBHelper.TIMESTAMP_COL + " DESC");
      cursor.move(number + 1);
      db.delete(DBHelper.TABLE_NAME, DBHelper.ID_COL + '=' + cursor.getString(0), null);
    } finally {
      close(cursor, db);
    }
  }

  public void addHistoryItem(Result result, ResultHandler handler) {
    // Do not save this item to the history if the preference is turned off, or the contents are
    // considered secure.
    if (!activity.getIntent().getBooleanExtra(Intents.Scan.SAVE_HISTORY, true) ||
        handler.areContentsSecure() || !enableHistory) {
      return;
    }

    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
    if (!prefs.getBoolean(PreferencesActivity.KEY_REMEMBER_DUPLICATES, false)) {
      deletePrevious(result.getText());
    }

    ContentValues values = new ContentValues();
    values.put(DBHelper.TEXT_COL, result.getText());
    values.put(DBHelper.FORMAT_COL, result.getBarcodeFormat().toString());
    values.put(DBHelper.DISPLAY_COL, handler.getDisplayContents().toString());
    values.put(DBHelper.TIMESTAMP_COL, System.currentTimeMillis());

    SQLiteOpenHelper helper = new DBHelper(activity);
    SQLiteDatabase db = null;
    try {
      db = helper.getWritableDatabase();      
      // Insert the new entry into the DB.
      db.insert(DBHelper.TABLE_NAME, DBHelper.TIMESTAMP_COL, values);
    } finally {
      close(null, db);
    }
  }

  public void addHistoryItemDetails(String itemID, String itemDetails) {
    // As we're going to do an update only we don't need need to worry
    // about the preferences; if the item wasn't saved it won't be udpated
    SQLiteOpenHelper helper = new DBHelper(activity);
    SQLiteDatabase db = null;    
    Cursor cursor = null;
    try {
      db = helper.getWritableDatabase();
      cursor = db.query(DBHelper.TABLE_NAME,
                        ID_DETAIL_COL_PROJECTION,
                        DBHelper.TEXT_COL + "=?",
                        new String[] { itemID },
                        null,
                        null,
                        DBHelper.TIMESTAMP_COL + " DESC",
                        "1");
      String oldID = null;
      String oldDetails = null;
      if (cursor.moveToNext()) {
        oldID = cursor.getString(0);
        oldDetails = cursor.getString(1);
      }

      if (oldID != null) {
        String newDetails;
        if (oldDetails == null) {
          newDetails = itemDetails;
        } else if (oldDetails.contains(itemDetails)) {
          newDetails = null;
        } else {
          newDetails = oldDetails + " : " + itemDetails;
        } 
        if (newDetails != null) {
          ContentValues values = new ContentValues();
          values.put(DBHelper.DETAILS_COL, newDetails);
          db.update(DBHelper.TABLE_NAME, values, DBHelper.ID_COL + "=?", new String[] { oldID });
        }
      }

    } finally {
      close(cursor, db);
    }
  }

  private void deletePrevious(String text) {
    SQLiteOpenHelper helper = new DBHelper(activity);
    SQLiteDatabase db = null;
    try {
      db = helper.getWritableDatabase();      
      db.delete(DBHelper.TABLE_NAME, DBHelper.TEXT_COL + "=?", new String[] { text });
    } finally {
      close(null, db);
    }
  }

  public void trimHistory() {
    SQLiteOpenHelper helper = new DBHelper(activity);
    SQLiteDatabase db = null;
    Cursor cursor = null;
    try {
      db = helper.getWritableDatabase();      
      cursor = db.query(DBHelper.TABLE_NAME,
                        ID_COL_PROJECTION,
                        null, null, null, null,
                        DBHelper.TIMESTAMP_COL + " DESC");
      cursor.move(MAX_ITEMS);
      while (cursor.moveToNext()) {
        String id = cursor.getString(0);
        Log.i(TAG, "Deleting scan history ID " + id);
        db.delete(DBHelper.TABLE_NAME, DBHelper.ID_COL + '=' + id, null);
      }
    } catch (SQLiteException sqle) {
      // We're seeing an error here when called in CaptureActivity.onCreate() in rare cases
      // and don't understand it. First theory is that it's transient so can be safely ignored.
      Log.w(TAG, sqle);
      // continue
    } finally {
      close(cursor, db);
    }
  }

  /**
   * <p>Builds a text representation of the scanning history. Each scan is encoded on one
   * line, terminated by a line break (\r\n). The values in each line are comma-separated,
   * and double-quoted. Double-quotes within values are escaped with a sequence of two
   * double-quotes. The fields output are:</p>
   *
   * <ol>
   *  <li>Raw text</li>
   *  <li>Display text</li>
   *  <li>Format (e.g. QR_CODE)</li>
   *  <li>Unix timestamp (milliseconds since the epoch)</li>
   *  <li>Formatted version of timestamp</li>
   *  <li>Supplemental info (e.g. price info for a product barcode)</li>
   * </ol>
   */
  CharSequence buildHistory() {
    SQLiteOpenHelper helper = new DBHelper(activity);
    SQLiteDatabase db = null;
    Cursor cursor = null;
    try {
      db = helper.getWritableDatabase();
      cursor = db.query(DBHelper.TABLE_NAME,
                        COLUMNS,
                        null, null, null, null,
                        DBHelper.TIMESTAMP_COL + " DESC");

      DateFormat format = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM);
      StringBuilder historyText = new StringBuilder(1000);
      while (cursor.moveToNext()) {

        historyText.append('"').append(massageHistoryField(cursor.getString(0))).append("\",");
        historyText.append('"').append(massageHistoryField(cursor.getString(1))).append("\",");
        historyText.append('"').append(massageHistoryField(cursor.getString(2))).append("\",");
        historyText.append('"').append(massageHistoryField(cursor.getString(3))).append("\",");

        // Add timestamp again, formatted
        long timestamp = cursor.getLong(3);
        historyText.append('"').append(massageHistoryField(
            format.format(new Date(timestamp)))).append("\",");

        // Above we're preserving the old ordering of columns which had formatted data in position 5

        historyText.append('"').append(massageHistoryField(cursor.getString(4))).append("\"\r\n");
      }
      return historyText;
    } finally {
      close(cursor, db);
    }
  }
  
  void clearHistory() {
    SQLiteOpenHelper helper = new DBHelper(activity);
    SQLiteDatabase db = null;
    try {
      db = helper.getWritableDatabase();      
      db.delete(DBHelper.TABLE_NAME, null, null);
    } finally {
      close(null, db);
    }
  }

  static Uri saveHistory(String history) {
    File bsRoot = new File(Environment.getExternalStorageDirectory(), "BarcodeScanner");
    File historyRoot = new File(bsRoot, "History");
    if (!historyRoot.exists() && !historyRoot.mkdirs()) {
      Log.w(TAG, "Couldn't make dir " + historyRoot);
      return null;
    }
    File historyFile = new File(historyRoot, "history-" + System.currentTimeMillis() + ".csv");
    OutputStreamWriter out = null;
    try {
      out = new OutputStreamWriter(new FileOutputStream(historyFile), Charset.forName("UTF-8"));
      out.write(history);
      return Uri.parse("file://" + historyFile.getAbsolutePath());
    } catch (IOException ioe) {
      Log.w(TAG, "Couldn't access file " + historyFile + " due to " + ioe);
      return null;
    } finally {
      if (out != null) {
        try {
          out.close();
        } catch (IOException ioe) {
          // do nothing
        }
      }
    }
  }

  private static String massageHistoryField(String value) {
    return value == null ? "" : value.replace("\"","\"\"");
  }
  
  private static void close(Cursor cursor, SQLiteDatabase database) {
    if (cursor != null) {
      cursor.close();
    }
    if (database != null) {
      database.close();
    }
  }

}
