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

import android.accounts.Account;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.IBinder;
import android.provider.ContactsContract.RawContacts;
import android.text.TextUtils;
import android.util.Log;
import android.widget.RemoteViews;
import android.widget.Toast;

import com.android.vcard.VCardConfig;
import com.android.vcard.VCardEntry;
import com.android.vcard.VCardEntryCommitter;
import com.android.vcard.VCardEntryConstructor;
import com.android.vcard.VCardEntryCounter;
import com.android.vcard.VCardEntryHandler;
import com.android.vcard.VCardInterpreter;
import com.android.vcard.VCardInterpreterCollection;
import com.android.vcard.VCardParser;
import com.android.vcard.VCardParser_V21;
import com.android.vcard.VCardParser_V30;
import com.android.vcard.VCardSourceDetector;
import com.android.vcard.exception.VCardException;
import com.android.vcard.exception.VCardNestedException;
import com.android.vcard.exception.VCardNotSupportedException;
import com.android.vcard.exception.VCardVersionException;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;

/**
 * The class responsible for importing vCard from one ore multiple Uris.
 */
public class ImportVCardService extends Service {
    private final static String LOG_TAG = "ImportVCardService";

    private class ProgressNotifier implements VCardEntryHandler {
        private final int mId;

        public ProgressNotifier(int id) {
            mId = id;
        }

        public void onStart() {
        }

        public void onEntryCreated(VCardEntry contactStruct) {
            mCurrentCount++;  // 1 origin.
            if (contactStruct.isIgnorable()) {
                return;
            }

            final Context context = ImportVCardService.this;
            // We don't use startEntry() since:
            // - We cannot know name there but here.
            // - There's high probability where name comes soon after the beginning of entry, so
            //   we don't need to hurry to show something.
            final String packageName = "com.android.contacts";
            final RemoteViews remoteViews = new RemoteViews(packageName,
                    R.layout.status_bar_ongoing_event_progress_bar);
            final String title = getString(R.string.reading_vcard_title);
            final String text = getString(R.string.progress_notifier_message,
                    String.valueOf(mCurrentCount),
                    String.valueOf(mTotalCount),
                    contactStruct.getDisplayName());

            // TODO: uploading image does not work correctly. (looks like a static image).
            remoteViews.setTextViewText(R.id.description, text);
            remoteViews.setProgressBar(R.id.progress_bar, mTotalCount, mCurrentCount,
                    mTotalCount == -1);
            final String percentage =
                    getString(R.string.percentage,
                            String.valueOf(mCurrentCount * 100/mTotalCount));
            remoteViews.setTextViewText(R.id.progress_text, percentage);
            remoteViews.setImageViewResource(R.id.appIcon, android.R.drawable.stat_sys_download);

            final Notification notification = new Notification();
            notification.icon = android.R.drawable.stat_sys_download;
            notification.flags |= Notification.FLAG_ONGOING_EVENT;
            notification.contentView = remoteViews;

            notification.contentIntent =
                    PendingIntent.getActivity(context, 0,
                            new Intent(context, ContactsListActivity.class), 0);
            mNotificationManager.notify(mId, notification);
        }

        public void onEnd() {
        }
    }

    private class VCardReadThread extends Thread {
        private final Context mContext;
        private final ContentResolver mResolver;
        private VCardParser mVCardParser;
        private boolean mCanceled;
        private final List<Uri> mErrorUris;
        private final List<Uri> mCreatedUris;

        public VCardReadThread() {
            mContext = ImportVCardService.this;
            mResolver = mContext.getContentResolver();
            mErrorUris = new ArrayList<Uri>();
            mCreatedUris = new ArrayList<Uri>();
        }

        @Override
        public void run() {
            while (!mCanceled) {
                mErrorUris.clear();
                mCreatedUris.clear();

                final Account account;
                final Uri[] uris;
                final int id;
                final boolean needReview;
                synchronized (mContext) {
                    if (mPendingInputs.size() == 0) {
                        mNowRunning = false;
                        break;
                    } else {
                        final PendingInput pendingInput = mPendingInputs.poll();
                        account = pendingInput.account;
                        uris = pendingInput.uris;
                        id = pendingInput.id;
                    }
                }
                runInternal(account, uris, id);
                doFinishNotification(id, uris);
            }
            Log.i(LOG_TAG, "Successfully imported. Total: " + mTotalCount);
            stopSelf();
        }

        private void runInternal(Account account, Uri[] uris, int id) {
            int totalCount = 0;
            final ArrayList<VCardSourceDetector> detectorList =
                new ArrayList<VCardSourceDetector>();
            // First scan all Uris with a default charset and try to understand an exact
            // charset to be used to each Uri. Note that detector would return null when
            // it does not know an appropriate charset, so stick to use the default
            // at that time.
            // TODO: notification for first scanning?
            for (Uri uri : uris) {
                if (mCanceled) {
                    return;
                }
                final VCardEntryCounter counter = new VCardEntryCounter();
                final VCardSourceDetector detector = new VCardSourceDetector();
                final VCardInterpreterCollection interpreterCollection =
                        new VCardInterpreterCollection(Arrays.asList(counter, detector));
                if (!readOneVCard(uri, VCardConfig.VCARD_TYPE_UNKNOWN, null,
                        interpreterCollection)) {
                    mErrorUris.add(uri);
                }

                totalCount += counter.getCount();
                detectorList.add(detector);
            }

            if (mErrorUris.size() > 0) {
                final StringBuilder builder = new StringBuilder();
                builder.append("Error happened on ");
                for (Uri errorUri : mErrorUris) {
                    builder.append("\"");
                    builder.append(errorUri.toString());
                    builder.append("\"");
                }
                Log.e(LOG_TAG, builder.toString());
                doErrorNotification(id);
                return;
            }

            if (uris.length != detectorList.size()) {
                Log.e(LOG_TAG,
                        "The number of Uris to be imported is different from that of " +
                        "charset to be used.");
                doErrorNotification(id);
                return;
            }

            // First scanning is over. Try to import each vCard, which causes side effects.
            mTotalCount = totalCount;
            mCurrentCount = 0;

            for (int i = 0; i < uris.length; i++) {
                if (mCanceled) {
                    Log.w(LOG_TAG, "Canceled during importing (with storing data in database)");
                    // TODO: implement cancel correctly.
                    return;
                }
                final Uri uri = uris[i];

                final VCardSourceDetector detector = detectorList.get(i);
                final int vcardType =  detector.getEstimatedType();  
                final String charset = detector.getEstimatedCharset();  // May be null.

                final VCardEntryConstructor constructor =
                        new VCardEntryConstructor(vcardType, account, charset);
                final VCardEntryCommitter committer = new VCardEntryCommitter(mResolver);
                constructor.addEntryHandler(committer);
                constructor.addEntryHandler(new ProgressNotifier(id));

                if (!readOneVCard(uri, vcardType, charset, constructor)) {
                        Log.e(LOG_TAG, "Failed to read \"" + uri.toString() + "\" " +
                                "while first scan was successful.");
                }
                final List<Uri> createdUris = committer.getCreatedUris();
                if (createdUris != null && createdUris.size() > 0) {
                    mCreatedUris.addAll(createdUris);
                } else {
                    Log.w(LOG_TAG, "Created Uris is null (src = " + uri.toString() + "\"");
                }
            }
        }

        private boolean readOneVCard(Uri uri, int vcardType, String charset,
                VCardInterpreter interpreter) {
            InputStream is;
            try {
                // TODO: use vcardType given from detector and stop trying to read the file twice.
                is = mResolver.openInputStream(uri);

                // We need synchronized since we need to handle mCanceled and mVCardParser
                // at once. In the worst case, a user may call cancel() just before recreating
                // mVCardParser.
                synchronized (this) {
                    mVCardParser = new VCardParser_V21(vcardType, charset);
                    if (mCanceled) {
                        mVCardParser.cancel();
                    }
                }

                try {
                    mVCardParser.parse(is, interpreter);
                } catch (VCardVersionException e1) {
                    try {
                        is.close();
                    } catch (IOException e) {
                    }
                    if (interpreter instanceof VCardEntryConstructor) {
                        // Let the object clean up internal temporal objects,
                        ((VCardEntryConstructor) interpreter).clear();
                    }
                    is = mResolver.openInputStream(uri);

                    synchronized (this) {
                        mVCardParser = new VCardParser_V30(vcardType, charset);
                        if (mCanceled) {
                            mVCardParser.cancel();
                        }
                    }

                    try {
                        mVCardParser.parse(is, interpreter);
                    } catch (VCardVersionException e2) {
                        throw new VCardException("vCard with unspported version.");
                    }
                } finally {
                    if (is != null) {
                        try {
                            is.close();
                        } catch (IOException e) {
                        }
                    }
                }
            } catch (IOException e) {
                Log.e(LOG_TAG, "IOException was emitted: " + e.getMessage());
                return false;
            } catch (VCardNestedException e) {
                // In the first scan, we may (correctly) encounter this exception.
                // We assume that we were able to detect the type of vCard before
                // the exception being thrown.
                //
                // In the second scan, we may (inappropriately) encounter it.
                // We silently ignore it, since
                // - It is really unusual situation.
                // - We cannot handle it by definition.
                // - Users cannot either.
                // - We should not accept unnecessarily complicated vCard, possibly by wrong manner.
                Log.w(LOG_TAG, "Nested Exception is found (it may be false-positive).");
            } catch (VCardNotSupportedException e) {
                return false;
            } catch (VCardException e) {
                return false;
            }
            return true;
        }

        private void doErrorNotification(int id) {
            final Notification notification = new Notification();
            notification.icon = android.R.drawable.stat_sys_download_done;
            final String title = mContext.getString(R.string.reading_vcard_failed_title);
            final PendingIntent intent =
                    PendingIntent.getActivity(mContext, 0, new Intent(), 0);
            notification.setLatestEventInfo(mContext, title, "", intent);
            mNotificationManager.notify(id, notification);
        }

        private void doFinishNotification(int id, Uri[] uris) {
            final Notification notification = new Notification();
            notification.icon = android.R.drawable.stat_sys_download_done;
            final String title = mContext.getString(R.string.reading_vcard_finished_title);

            final Intent intent;
            final long rawContactId = ContentUris.parseId(mCreatedUris.get(0));
            final Uri contactUri = RawContacts.getContactLookupUri(
                    getContentResolver(), ContentUris.withAppendedId(
                            RawContacts.CONTENT_URI, rawContactId));
            intent = new Intent(Intent.ACTION_VIEW, contactUri);

            final String text = ((uris.length == 1) ? uris[0].getPath() : "");
            final PendingIntent pendingIntent =
                    PendingIntent.getActivity(mContext, 0, intent, 0);
            notification.setLatestEventInfo(mContext, title, text, pendingIntent);
            mNotificationManager.notify(id, notification);
        }

        // We need synchronized since we need to handle mCanceled and mVCardParser at once.
        public synchronized void cancel() {
            mCanceled = true;
            if (mVCardParser != null) {
                mVCardParser.cancel();
            }
        }

        public void onCancel(DialogInterface dialog) {
            cancel();
        }
    }

    private static class PendingInput {
        public final Account account;
        public final Uri[] uris;
        public final int id;

        public PendingInput(Account account, Uri[] uris, int id) {
            this.account = account;
            this.uris = uris;
            this.id = id;
        }
    }

    // The two classes bellow must be called inside the synchronized block, using this context.
    private boolean mNowRunning;
    private final Queue<PendingInput> mPendingInputs = new LinkedList<PendingInput>();

    private NotificationManager mNotificationManager;
    private Thread mThread;
    private int mTotalCount;
    private int mCurrentCount;

    private Uri[] tryGetUris(Intent intent) {
        final String[] uriStrings =
                intent.getStringArrayExtra(ImportVCardActivity.VCARD_URI_ARRAY);
        if (uriStrings == null || uriStrings.length == 0) {
            Log.e(LOG_TAG, "Given uri array is empty");
            return null;
        }

        final int length = uriStrings.length;
        final Uri[] uris = new Uri[length];
        for (int i = 0; i < length; i++) {
            uris[i] = Uri.parse(uriStrings[i]);
        }

        return uris;
    }

    private Account tryGetAccount(Intent intent) {
        if (intent == null) {
            Log.w(LOG_TAG, "Intent is null");
            return null;
        }

        final String accountName = intent.getStringExtra("account_name");
        final String accountType = intent.getStringExtra("account_type");
        if (!TextUtils.isEmpty(accountName) && !TextUtils.isEmpty(accountType)) {
            return new Account(accountName, accountType);
        } else {
            Log.w(LOG_TAG, "Account is not set.");
            return null;
        }
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if (mNotificationManager == null) {
            mNotificationManager =
                    (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
        }

        final Account account = tryGetAccount(intent);
        final Uri[] uris = tryGetUris(intent);
        if (uris == null) {
            Log.e(LOG_TAG, "Uris are null.");
            Toast.makeText(this, getString(R.string.reading_vcard_failed_title),
                    Toast.LENGTH_LONG).show();
            stopSelf();
            return START_NOT_STICKY;
        }

        synchronized (this) {
            mPendingInputs.add(new PendingInput(account, uris, startId));
            if (!mNowRunning) {
                Toast.makeText(this, getString(R.string.vcard_importer_start_message),
                        Toast.LENGTH_LONG).show();
                // Assume thread is alredy broken.
                // Even when it still exists, it never scan the PendingInput newly added above.
                mNowRunning = true;
                mThread = new VCardReadThread();
                mThread.start();
            } else {
                Toast.makeText(this, getString(R.string.vcard_importer_will_start_message),
                        Toast.LENGTH_LONG).show();
            }
        }

        return START_NOT_STICKY;
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
}
