/*
 * Copyright (C) 2013 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.inputmethod.latin;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.os.Environment;

import com.android.inputmethod.latin.makedict.FormatSpec.FileHeader;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Locale;

/**
 * A class to read a local file as a dictionary for debugging purposes.
 */
public class ExternalDictionaryGetterForDebug {
    private static final String SOURCE_FOLDER = Environment.getExternalStorageDirectory().getPath()
            + "/Download";

    private static String[] findDictionariesInTheDownloadedFolder() {
        final File[] files = new File(SOURCE_FOLDER).listFiles();
        final ArrayList<String> eligibleList = CollectionUtils.newArrayList();
        for (File f : files) {
            final FileHeader header = DictionaryInfoUtils.getDictionaryFileHeaderOrNull(f);
            if (null == header) continue;
            eligibleList.add(f.getName());
        }
        return eligibleList.toArray(new String[0]);
    }

    public static void chooseAndInstallDictionary(final Context context) {
        final String[] fileNames = findDictionariesInTheDownloadedFolder();
        if (0 == fileNames.length) {
            showNoFileDialog(context);
        } else if (1 == fileNames.length) {
            askInstallFile(context, fileNames[0]);
        } else {
            showChooseFileDialog(context, fileNames);
        }
    }

    private static void showNoFileDialog(final Context context) {
        new AlertDialog.Builder(context)
                .setMessage(R.string.read_external_dictionary_no_files_message)
                .setPositiveButton(android.R.string.ok, new OnClickListener() {
                    @Override
                    public void onClick(final DialogInterface dialog, final int which) {
                        dialog.dismiss();
                    }
                }).create().show();
    }

    private static void showChooseFileDialog(final Context context, final String[] fileNames) {
        final AlertDialog.Builder builder = new AlertDialog.Builder(context);
        builder.setTitle(R.string.read_external_dictionary_multiple_files_title)
                .setItems(fileNames, new OnClickListener() {
                    @Override
                    public void onClick(final DialogInterface dialog, final int which) {
                        askInstallFile(context, fileNames[which]);
                    }
                })
                .create().show();
    }

    private static void askInstallFile(final Context context, final String fileName) {
        final File file = new File(SOURCE_FOLDER, fileName.toString());
        final FileHeader header = DictionaryInfoUtils.getDictionaryFileHeaderOrNull(file);
        final StringBuilder message = new StringBuilder();
        final String locale = header.getLocaleString();
        for (String key : header.mDictionaryOptions.mAttributes.keySet()) {
            message.append(key + " = " + header.mDictionaryOptions.mAttributes.get(key));
            message.append("\n");
        }
        final String languageName = LocaleUtils.constructLocaleFromString(locale)
                .getDisplayName(Locale.getDefault());
        final String title = String.format(
                context.getString(R.string.read_external_dictionary_confirm_install_message),
                languageName);
        new AlertDialog.Builder(context)
                .setTitle(title)
                .setMessage(message)
                .setNegativeButton(android.R.string.cancel, new OnClickListener() {
                    @Override
                    public void onClick(final DialogInterface dialog, final int which) {
                        dialog.dismiss();
                    }
                }).setPositiveButton(android.R.string.ok, new OnClickListener() {
                    @Override
                    public void onClick(final DialogInterface dialog, final int which) {
                        installFile(context, file, header);
                        dialog.dismiss();
                    }
                }).create().show();
    }

    private static void installFile(final Context context, final File file,
            final FileHeader header) {
        BufferedOutputStream outputStream = null;
        File tempFile = null;
        try {
            final String locale = header.getLocaleString();
            // Create the id for a main dictionary for this locale
            final String id = BinaryDictionaryGetter.MAIN_DICTIONARY_CATEGORY
                    + BinaryDictionaryGetter.ID_CATEGORY_SEPARATOR + locale;
            final String finalFileName = DictionaryInfoUtils.getCacheFileName(id, locale, context);
            final String tempFileName = BinaryDictionaryGetter.getTempFileName(id, context);
            tempFile = new File(tempFileName);
            tempFile.delete();
            outputStream = new BufferedOutputStream(new FileOutputStream(tempFile));
            final BufferedInputStream bufferedStream = new BufferedInputStream(
                    new FileInputStream(file));
            BinaryDictionaryFileDumper.checkMagicAndCopyFileTo(bufferedStream, outputStream);
            outputStream.flush();
            final File finalFile = new File(finalFileName);
            finalFile.delete();
            if (!tempFile.renameTo(finalFile)) {
                throw new IOException("Can't move the file to its final name");
            }
        } catch (IOException e) {
            // There was an error: show a dialog
            new AlertDialog.Builder(context)
                    .setTitle(R.string.error)
                    .setMessage(e.toString())
                    .setPositiveButton(android.R.string.ok, new OnClickListener() {
                        @Override
                        public void onClick(final DialogInterface dialog, final int which) {
                            dialog.dismiss();
                        }
                    }).create().show();
            return;
        } finally {
            try {
                if (null != outputStream) outputStream.close();
                if (null != tempFile) tempFile.delete();
            } catch (IOException e) {
                // Don't do anything
            }
        }
    }
}
