/*
 * BRLTTY - A background process providing access to the console screen (when in
 *          text mode) for a blind person using a refreshable braille display.
 *
 * Copyright (C) 1995-2012 by The BRLTTY Developers.
 *
 * BRLTTY comes with ABSOLUTELY NO WARRANTY.
 *
 * This is free software, placed under the terms of the
 * GNU General Public License, as published by the Free Software
 * Foundation; either version 2 of the License, or (at your option) any
 * later version. Please see the file LICENSE-GPL for details.
 *
 * Web Page: http://mielke.cc/brltty/
 *
 * This software is maintained by Dave Mielke <dave@mielke.cc>.
 */

package org.a11y.brltty.android;

import org.a11y.brltty.core.*;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import java.io.File;
import java.io.FileOutputStream;

import android.util.Log;

import android.content.Context;
import android.content.res.AssetManager;

public class CoreThread extends Thread {
  private final String LOG_TAG = this.getClass().getName();

  private final Context coreContext;

  public static final int DATA_MODE = Context.MODE_PRIVATE;
  public static final String DRIVERS_SUBDIRECTORY = "drivers";
  public static final String TABLES_SUBDIRECTORY = "tables";

  private final File getDataDirectory (String subdirectory) {
    return coreContext.getDir(subdirectory, DATA_MODE);
  }

  private final void extractAsset (AssetManager assets, String type, File path) {
    String asset = new File(type, path.getName()).getPath();
    Log.d(LOG_TAG, "extracting asset: " + asset + " -> " + path);

    try {
      InputStream input = null;
      OutputStream output = null;

      try {
        input = assets.open(asset);
        output = new FileOutputStream(path);

        byte[] buffer = new byte[0X4000];
        int count;

        while ((count = input.read(buffer)) > 0) {
          output.write(buffer, 0, count);
        }
      } finally {
        if (input != null) {
          input.close();
        }

        if (output != null) {
          output.close();
        }
      }
    } catch (IOException exception) {
      Log.e(LOG_TAG, "cannot extract asset: " + asset + " -> " + path, exception);
    }
  }

  private final void extractAssets (AssetManager assets, String type) {
    File directory = getDataDirectory(type);

    if (directory.canWrite()) {
      try {
        String[] files = assets.list(type);

        for (String file : files) {
          File path = new File(directory, file);

          if (path.exists()) {
            if (!path.canWrite()) {
              continue;
            }

            path.delete();
          }

          extractAsset(assets, type, path);
          path.setReadOnly();
        }

        directory.setReadOnly();
      } catch (IOException exception) {
        Log.e(LOG_TAG, "cannot list assets directory: " + type, exception);
      }
    }
  }

  private final void extractAssets () {
    AssetManager assets = coreContext.getAssets();
    extractAssets(assets, TABLES_SUBDIRECTORY);
  }

  CoreThread (Context context) {
    super("Core");
    coreContext = context;

    UsbHelper.construct(coreContext);
  }

  @Override
  public void run () {
    extractAssets();

    ArgumentsBuilder builder = new ArgumentsBuilder();

    // required settings
    builder.setForegroundExecution(true);
    builder.setTablesDirectory(getDataDirectory(TABLES_SUBDIRECTORY).getPath());
    builder.setDriversDirectory(getDataDirectory(DRIVERS_SUBDIRECTORY).getPath());
    builder.setWritableDirectory(coreContext.getFilesDir().getPath());

    // optional settings
    builder.setLogLevel(LogLevel.DEBUG);
    builder.setLogFile("/data/local/tmp/brltty.log");

    // settings for testing - should be removed
    builder.setBrailleDriver("al");
    builder.setBrailleDevice("usb:,bluetooth:00:A0:96:18:54:7E");

    String[] arguments = builder.getArguments();
    CoreWrapper.run(arguments);
  }
}

@@ -1173,37 +1173,32 @@
 ng D
-RIVERS_SUBDIRECTORY = %22driver
+ATA_TYPE_TABLES = %22table
 s%22;%0A
@@ -1230,36 +1230,35 @@
 ing 
-TABLES_SUBDIRECTORY = %22table
+DATA_TYPE_DRIVERS = %22driver
 s%22;%0A
@@ -1304,28 +1304,20 @@
 (String 
-subdirectory
+type
 ) %7B%0A    
@@ -1346,20 +1346,12 @@
 Dir(
-subdirectory
+type
 , DA
@@ -3009,35 +3009,78 @@
 assets, 
-TABLES_SUBDIRECTORY
+DATA_TYPE_TABLES);%0A    extractAssets(assets, DATA_TYPE_DRIVERS
 );%0A  %7D%0A%0A
@@ -3434,27 +3434,24 @@
 ory(
-TABLES_SUBDIRECTORY
+DATA_TYPE_TABLES
 ).ge
@@ -3514,27 +3514,24 @@
 ry(D
-RIVERS_SUBDIRECTORY
+ATA_TYPE_DRIVERS
 ).ge

Extract the driver objects from the assets. (dm)