/*
 * 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.development;

import android.app.Activity;
import android.app.PendingIntent;
import android.app.Dialog;
import android.app.AlertDialog;
import android.content.res.TypedArray;
import android.content.pm.RegisteredServicesCache;
import android.content.pm.RegisteredServicesCacheListener;
import android.content.SyncAdapterType;
import android.content.ISyncAdapter;
import android.content.ISyncContext;
import android.content.ServiceConnection;
import android.content.ComponentName;
import android.content.SyncResult;
import android.content.Intent;
import android.content.Context;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.widget.ArrayAdapter;
import android.widget.AdapterView;
import android.widget.Spinner;
import android.widget.Button;
import android.widget.TextView;
import android.widget.ListView;
import android.util.AttributeSet;
import android.provider.Settings;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.view.View;
import android.view.LayoutInflater;

import java.util.Collection;

public class SyncAdapterDriver extends Activity
        implements RegisteredServicesCacheListener<SyncAdapterType>,
        AdapterView.OnItemClickListener {
    private Spinner mSyncAdapterSpinner;

    private Button mBindButton;
    private Button mUnbindButton;
    private TextView mBoundAdapterTextView;
    private Button mStartSyncButton;
    private Button mCancelSyncButton;
    private TextView mStatusTextView;
    private Object[] mSyncAdapters;
    private SyncAdaptersCache mSyncAdaptersCache;
    private final Object mSyncAdaptersLock = new Object();

    private static final int DIALOG_ID_PICK_ACCOUNT = 1;
    private ListView mAccountPickerView = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mSyncAdaptersCache = new SyncAdaptersCache(this);
        setContentView(R.layout.sync_adapter_driver);

        mSyncAdapterSpinner = (Spinner) findViewById(R.id.sync_adapters_spinner);
        mBindButton = (Button) findViewById(R.id.bind_button);
        mUnbindButton = (Button) findViewById(R.id.unbind_button);
        mBoundAdapterTextView = (TextView) findViewById(R.id.bound_adapter_text_view);

        mStartSyncButton = (Button) findViewById(R.id.start_sync_button);
        mCancelSyncButton = (Button) findViewById(R.id.cancel_sync_button);

        mStatusTextView = (TextView) findViewById(R.id.status_text_view);

        getSyncAdapters();
        mSyncAdaptersCache.setListener(this, null /* Handler */);
    }

    protected void onDestroy() {
        mSyncAdaptersCache.close();
        super.onDestroy();
    }

    private void getSyncAdapters() {
        Collection<RegisteredServicesCache.ServiceInfo<SyncAdapterType>> all =
                mSyncAdaptersCache.getAllServices();
        synchronized (mSyncAdaptersLock) {
            mSyncAdapters = new Object[all.size()];
            String[] names = new String[mSyncAdapters.length];
            int i = 0;
            for (RegisteredServicesCache.ServiceInfo<SyncAdapterType> item : all) {
                mSyncAdapters[i] = item;
                names[i] = item.type.authority + " - " + item.type.accountType;
                i++;
            }

            ArrayAdapter<String> adapter =
                    new ArrayAdapter<String>(this,
                    R.layout.sync_adapter_item, names);
            mSyncAdapterSpinner.setAdapter(adapter);
        }
    }

    void updateUi() {
        boolean isBound;
        boolean hasServiceConnection;
        synchronized (mServiceConnectionLock) {
            hasServiceConnection = mActiveServiceConnection != null;
            isBound = hasServiceConnection && mActiveServiceConnection.mBoundSyncAdapter != null;
        }
        mStartSyncButton.setEnabled(isBound);
        mCancelSyncButton.setEnabled(isBound);
        mBindButton.setEnabled(!hasServiceConnection);
        mUnbindButton.setEnabled(hasServiceConnection);
    }

    public void startSyncSelected(View view) {
        synchronized (mServiceConnectionLock) {
            ISyncAdapter syncAdapter = null;
            if (mActiveServiceConnection != null) {
                syncAdapter = mActiveServiceConnection.mBoundSyncAdapter;
            }

            if (syncAdapter != null) {
                removeDialog(DIALOG_ID_PICK_ACCOUNT);

                mAccountPickerView = (ListView) LayoutInflater.from(this).inflate(
                        R.layout.account_list_view, null);
                mAccountPickerView.setOnItemClickListener(this);
                Account accounts[] = AccountManager.get(this).getAccountsByType(
                        mActiveServiceConnection.mSyncAdapter.type.accountType);
                String[] accountNames = new String[accounts.length];
                for (int i = 0; i < accounts.length; i++) {
                    accountNames[i] = accounts[i].name;
                }
                ArrayAdapter<String> adapter =
                        new ArrayAdapter<String>(SyncAdapterDriver.this,
                        android.R.layout.simple_list_item_1, accountNames);
                mAccountPickerView.setAdapter(adapter);

                showDialog(DIALOG_ID_PICK_ACCOUNT);
            }
        }
        updateUi();
    }

    private void startSync(String accountName) {
        synchronized (mServiceConnectionLock) {
            ISyncAdapter syncAdapter = null;
            if (mActiveServiceConnection != null) {
                syncAdapter = mActiveServiceConnection.mBoundSyncAdapter;
            }

            if (syncAdapter != null) {
                try {
                    mStatusTextView.setText(
                            getString(R.string.status_starting_sync_format, accountName));
                    Account account = new Account(accountName,
                            mActiveServiceConnection.mSyncAdapter.type.accountType);
                    syncAdapter.startSync(mActiveServiceConnection,
                            mActiveServiceConnection.mSyncAdapter.type.authority,
                            account, new Bundle());
                } catch (RemoteException e) {
                    mStatusTextView.setText(
                            getString(R.string.status_remote_exception_while_starting_sync));
                }
            }
        }
        updateUi();
    }

    public void cancelSync(View view) {
        synchronized (mServiceConnectionLock) {
            ISyncAdapter syncAdapter = null;
            if (mActiveServiceConnection != null) {
                syncAdapter = mActiveServiceConnection.mBoundSyncAdapter;
            }

            if (syncAdapter != null) {
                try {
                    mStatusTextView.setText(getString(R.string.status_canceled_sync));
                    syncAdapter.cancelSync(mActiveServiceConnection);
                } catch (RemoteException e) {
                    mStatusTextView.setText(
                            getString(R.string.status_remote_exception_while_canceling_sync));
                }
            }
        }
        updateUi();
    }

    public void onServiceChanged(SyncAdapterType type, boolean removed) {
        getSyncAdapters();
    }

    @Override
    protected Dialog onCreateDialog(final int id) {
        if (id == DIALOG_ID_PICK_ACCOUNT) {
            AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setMessage(R.string.select_account_to_sync);
            builder.setInverseBackgroundForced(true);
            builder.setView(mAccountPickerView);
            return builder.create();
        }
        return super.onCreateDialog(id);
    }

    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        TextView item = (TextView) view;
        final String accountName = item.getText().toString();
        dismissDialog(DIALOG_ID_PICK_ACCOUNT);
        startSync(accountName);
    }

    private class MyServiceConnection extends ISyncContext.Stub implements ServiceConnection {
        private volatile ISyncAdapter mBoundSyncAdapter;
        final RegisteredServicesCache.ServiceInfo<SyncAdapterType> mSyncAdapter;

        public MyServiceConnection(
                RegisteredServicesCache.ServiceInfo<SyncAdapterType> syncAdapter) {
            mSyncAdapter = syncAdapter;
        }

        public void onServiceConnected(ComponentName name, IBinder service) {
            mBoundSyncAdapter = ISyncAdapter.Stub.asInterface(service);
            final SyncAdapterType type = mActiveServiceConnection.mSyncAdapter.type;
            mBoundAdapterTextView.setText(getString(R.string.binding_connected_format,
                    type.authority, type.accountType));
            updateUi();
        }

        public void onServiceDisconnected(ComponentName name) {
            mBoundAdapterTextView.setText(getString(R.string.binding_not_connected));
            mBoundSyncAdapter = null;
            updateUi();
        }

        public void sendHeartbeat() {
            runOnUiThread(new Runnable() {
                public void run() {
                    uiThreadSendHeartbeat();
                }
            });
        }

        public void uiThreadSendHeartbeat() {
            mStatusTextView.setText(getString(R.string.status_received_heartbeat));
        }

        public void uiThreadOnFinished(SyncResult result) {
            if (result.hasError()) {
                mStatusTextView.setText(
                        getString(R.string.status_sync_failed_format, result.toString()));
            } else {
                mStatusTextView.setText(
                        getString(R.string.status_sync_succeeded_format, result.toString()));
            }
        }

        public void onFinished(final SyncResult result) throws RemoteException {
            runOnUiThread(new Runnable() {
                public void run() {
                    uiThreadOnFinished(result);
                }
            });
        }
    }

    final Object mServiceConnectionLock = new Object();
    MyServiceConnection mActiveServiceConnection;

    public void initiateBind(View view) {
        synchronized (mServiceConnectionLock) {
            if (mActiveServiceConnection != null) {
                mStatusTextView.setText(getString(R.string.status_already_bound));
                return;
            }

            RegisteredServicesCache.ServiceInfo<SyncAdapterType> syncAdapter =
                    getSelectedSyncAdapter();
            if (syncAdapter == null) {
                mStatusTextView.setText(getString(R.string.status_sync_adapter_not_selected));
                return;
            }

            mActiveServiceConnection = new MyServiceConnection(syncAdapter);

            Intent intent = new Intent();
            intent.setAction("android.content.SyncAdapter");
            intent.setComponent(syncAdapter.componentName);
            intent.putExtra(Intent.EXTRA_CLIENT_LABEL,
                    com.android.internal.R.string.sync_binding_label);
            intent.putExtra(Intent.EXTRA_CLIENT_INTENT, PendingIntent.getActivity(
                    this, 0, new Intent(Settings.ACTION_SYNC_SETTINGS), 0));
            if (!bindService(intent, mActiveServiceConnection, Context.BIND_AUTO_CREATE)) {
                mBoundAdapterTextView.setText(getString(R.string.binding_bind_failed));
                mActiveServiceConnection = null;
                return;
            }
            mBoundAdapterTextView.setText(getString(R.string.binding_waiting_for_connection));
        }
        updateUi();
    }

    public void initiateUnbind(View view) {
        synchronized (mServiceConnectionLock) {
            if (mActiveServiceConnection == null) {
                return;
            }
            mBoundAdapterTextView.setText("");
            unbindService(mActiveServiceConnection);
            mActiveServiceConnection = null;
        }
        updateUi();
    }

    private RegisteredServicesCache.ServiceInfo<SyncAdapterType> getSelectedSyncAdapter() {
        synchronized (mSyncAdaptersLock) {
            final int position = mSyncAdapterSpinner.getSelectedItemPosition();
            if (position == AdapterView.INVALID_POSITION) {
                return null;
            }
            try {
                //noinspection unchecked
                return (RegisteredServicesCache.ServiceInfo<SyncAdapterType>)
                        mSyncAdapters[position];
            } catch (Exception e) {
                return null;
            }
        }
    }

    static class SyncAdaptersCache extends RegisteredServicesCache<SyncAdapterType> {
        private static final String SERVICE_INTERFACE = "android.content.SyncAdapter";
        private static final String SERVICE_META_DATA = "android.content.SyncAdapter";
        private static final String ATTRIBUTES_NAME = "sync-adapter";

        SyncAdaptersCache(Context context) {
            super(context, SERVICE_INTERFACE, SERVICE_META_DATA, ATTRIBUTES_NAME, null);
        }

        public SyncAdapterType parseServiceAttributes(String packageName, AttributeSet attrs) {
            TypedArray sa = mContext.getResources().obtainAttributes(attrs,
                    com.android.internal.R.styleable.SyncAdapter);
            try {
                final String authority =
                        sa.getString(com.android.internal.R.styleable.SyncAdapter_contentAuthority);
                final String accountType =
                        sa.getString(com.android.internal.R.styleable.SyncAdapter_accountType);
                if (authority == null || accountType == null) {
                    return null;
                }
                final boolean userVisible = sa.getBoolean(
                        com.android.internal.R.styleable.SyncAdapter_userVisible, true);
                final boolean supportsUploading = sa.getBoolean(
                        com.android.internal.R.styleable.SyncAdapter_supportsUploading, true);
                return new SyncAdapterType(authority, accountType, userVisible, supportsUploading);
            } finally {
                sa.recycle();
            }
        }
    }
}
