/*
 * Copyright (C) 2010 Google Inc.
 *
 * 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.googlecode.android_scripting.facade;

import android.app.Service;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.provider.ContactsContract;

import com.googlecode.android_scripting.jsonrpc.RpcReceiver;
import com.googlecode.android_scripting.rpc.Rpc;
import com.googlecode.android_scripting.rpc.RpcOptional;
import com.googlecode.android_scripting.rpc.RpcParameter;

import java.util.ArrayList;
import java.util.List;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

/**
 * Provides access to contacts related functionality.
 * 
 * @author MeanEYE.rcf (meaneye.rcf@gmail.com
 */
public class ContactsFacade extends RpcReceiver {
  private static final Uri CONTACTS_URI = Uri.parse("content://contacts/people");
  private final ContentResolver mContentResolver;
  private final Service mService;
  private final CommonIntentsFacade mCommonIntentsFacade;
  public Uri mPhoneContent = null;
  public String mContactId;
  public String mPrimary;
  public String mPhoneNumber;
  public String mHasPhoneNumber;

  public ContactsFacade(FacadeManager manager) {
    super(manager);
    mService = manager.getService();
    mContentResolver = mService.getContentResolver();
    mCommonIntentsFacade = manager.getReceiver(CommonIntentsFacade.class);
    try {
      // Backward compatibility... get contract stuff using reflection
      Class<?> phone = Class.forName("android.provider.ContactsContract$CommonDataKinds$Phone");
      mPhoneContent = (Uri) phone.getField("CONTENT_URI").get(null);
      mContactId = (String) phone.getField("CONTACT_ID").get(null);
      mPrimary = (String) phone.getField("IS_PRIMARY").get(null);
      mPhoneNumber = (String) phone.getField("NUMBER").get(null);
      mHasPhoneNumber = (String) phone.getField("HAS_PHONE_NUMBER").get(null);
    } catch (Exception e) {
    }
  }

  private Uri buildUri(Integer id) {
    Uri uri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, id);
    return uri;
  }

  @Rpc(description = "Displays a list of contacts to pick from.", returns = "A map of result values.")
  public Intent pickContact() throws JSONException {
    return mCommonIntentsFacade.pick("content://contacts/people");
  }

  @Rpc(description = "Displays a list of phone numbers to pick from.", returns = "The selected phone number.")
  public String pickPhone() throws JSONException {
    String result = null;
    Intent data = mCommonIntentsFacade.pick("content://contacts/phones");
    if (data != null) {
      Uri phoneData = data.getData();
      Cursor cursor = mService.getContentResolver().query(phoneData, null, null, null, null);
      if (cursor != null) {
        if (cursor.moveToFirst()) {
          result = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.PhoneLookup.NUMBER));
        }
        cursor.close();
      }
    }
    return result;
  }

  @Rpc(description = "Returns a List of all possible attributes for contacts.")
  public List<String> contactsGetAttributes() {
    List<String> result = new ArrayList<String>();
    Cursor cursor = mContentResolver.query(CONTACTS_URI, null, null, null, null);
    if (cursor != null) {
      String[] columns = cursor.getColumnNames();
      for (int i = 0; i < columns.length; i++) {
        result.add(columns[i]);
      }
      cursor.close();
    }
    return result;
  }

  // TODO(MeanEYE.rcf): Add ability to narrow selection by providing named pairs of attributes.
  @Rpc(description = "Returns a List of all contact IDs.")
  public List<Integer> contactsGetIds() {
    List<Integer> result = new ArrayList<Integer>();
    String[] columns = { "_id" };
    Cursor cursor = mContentResolver.query(CONTACTS_URI, columns, null, null, null);
    if (cursor != null) {
      while (cursor.moveToNext()) {
        result.add(cursor.getInt(0));
      }
      cursor.close();
    }
    return result;
  }

  @Rpc(description = "Returns a List of all contacts.", returns = "a List of contacts as Maps")
  public List<JSONObject> contactsGet(
      @RpcParameter(name = "attributes") @RpcOptional JSONArray attributes) throws JSONException {
    List<JSONObject> result = new ArrayList<JSONObject>();
    String[] columns;
    if (attributes == null || attributes.length() == 0) {
      // In case no attributes are specified we set the default ones.
      columns = new String[] { "_id", "name", "primary_phone", "primary_email", "type" };
    } else {
      // Convert selected attributes list into usable string list.
      columns = new String[attributes.length()];
      for (int i = 0; i < attributes.length(); i++) {
        columns[i] = attributes.getString(i);
      }
    }
    List<String> queryList = new ArrayList<String>();
    for (String s : columns) {
      queryList.add(s);
    }
    if (!queryList.contains("_id")) {
      queryList.add("_id");
    }

    String[] query = queryList.toArray(new String[queryList.size()]);
    Cursor cursor = mContentResolver.query(CONTACTS_URI, query, null, null, null);
    if (cursor != null) {
      int idIndex = cursor.getColumnIndex("_id");
      while (cursor.moveToNext()) {
        String id = cursor.getString(idIndex);
        JSONObject message = new JSONObject();
        for (int i = 0; i < columns.length; i++) {
          String key = columns[i];
          String value = cursor.getString(cursor.getColumnIndex(key));
          if (mPhoneNumber != null) {
            if (key.equals("primary_phone")) {
              value = findPhone(id);
            }
          }
          message.put(key, value);
        }
        result.add(message);
      }
      cursor.close();
    }
    return result;
  }

  private String findPhone(String id) {
    String result = null;
    if (id == null || id.equals("")) {
      return result;
    }
    try {
      if (Integer.parseInt(id) > 0) {
        Cursor pCur =
            mContentResolver.query(mPhoneContent, new String[] { mPhoneNumber }, mContactId
                + " = ? and " + mPrimary + "=1", new String[] { id }, null);
        if (pCur != null) {
          pCur.getColumnNames();
          while (pCur.moveToNext()) {
            result = pCur.getString(0);
            break;
          }
        }
        pCur.close();
      }
    } catch (Exception e) {
      return null;
    }
    return result;
  }

  @Rpc(description = "Returns contacts by ID.")
  public JSONObject contactsGetById(@RpcParameter(name = "id") Integer id,
      @RpcParameter(name = "attributes") @RpcOptional JSONArray attributes) throws JSONException {
    JSONObject result = null;
    Uri uri = buildUri(id);
    String[] columns;
    if (attributes == null || attributes.length() == 0) {
      // In case no attributes are specified we set the default ones.
      columns = new String[] { "_id", "name", "primary_phone", "primary_email", "type" };
    } else {
      // Convert selected attributes list into usable string list.
      columns = new String[attributes.length()];
      for (int i = 0; i < attributes.length(); i++) {
        columns[i] = attributes.getString(i);
      }
    }
    Cursor cursor = mContentResolver.query(uri, columns, null, null, null);
    if (cursor != null) {
      result = new JSONObject();
      cursor.moveToFirst();
      for (int i = 0; i < columns.length; i++) {
        result.put(columns[i], cursor.getString(i));
      }
      cursor.close();
    }
    return result;
  }

  // TODO(MeanEYE.rcf): Add ability to narrow selection by providing named pairs of attributes.
  @Rpc(description = "Returns the number of contacts.")
  public Integer contactsGetCount() {
    Integer result = 0;
    Cursor cursor = mContentResolver.query(CONTACTS_URI, null, null, null, null);
    if (cursor != null) {
      result = cursor.getCount();
      cursor.close();
    }
    return result;
  }

  private String[] jsonToArray(JSONArray array) throws JSONException {
    String[] result = null;
    if (array != null && array.length() > 0) {
      result = new String[array.length()];
      for (int i = 0; i < array.length(); i++) {
        result[i] = array.getString(i);
      }
    }
    return result;
  }

  /**
   * Exactly as per <a href=
   * "http://developer.android.com/reference/android/content/ContentResolver.html#query%28android.net.Uri,%20java.lang.String[],%20java.lang.String,%20java.lang.String[],%20java.lang.String%29"
   * >ContentResolver.query</a>
   */
  @Rpc(description = "Content Resolver Query", returns = "result of query as Maps")
  public List<JSONObject> queryContent(
      @RpcParameter(name = "uri", description = "The URI, using the content:// scheme, for the content to retrieve.") String uri,
      @RpcParameter(name = "attributes", description = "A list of which columns to return. Passing null will return all columns") @RpcOptional JSONArray attributes,
      @RpcParameter(name = "selection", description = "A filter declaring which rows to return") @RpcOptional String selection,
      @RpcParameter(name = "selectionArgs", description = "You may include ?s in selection, which will be replaced by the values from selectionArgs") @RpcOptional JSONArray selectionArgs,
      @RpcParameter(name = "order", description = "How to order the rows") @RpcOptional String order)
      throws JSONException {
    List<JSONObject> result = new ArrayList<JSONObject>();
    String[] columns = jsonToArray(attributes);
    String[] args = jsonToArray(selectionArgs);
    Cursor cursor = mContentResolver.query(Uri.parse(uri), columns, selection, args, order);
    if (cursor != null) {
      String[] names = cursor.getColumnNames();
      while (cursor.moveToNext()) {
        JSONObject message = new JSONObject();
        for (int i = 0; i < cursor.getColumnCount(); i++) {
          String key = names[i];
          String value = cursor.getString(i);
          message.put(key, value);
        }
        result.add(message);
      }
      cursor.close();
    }
    return result;
  }

  @Rpc(description = "Content Resolver Query Attributes", returns = "a list of available columns for a given content uri")
  public JSONArray queryAttributes(
      @RpcParameter(name = "uri", description = "The URI, using the content:// scheme, for the content to retrieve.") String uri)
      throws JSONException {
    JSONArray result = new JSONArray();
    Cursor cursor = mContentResolver.query(Uri.parse(uri), null, "1=0", null, null);
    if (cursor != null) {
      String[] names = cursor.getColumnNames();
      for (String name : names) {
        result.put(name);
      }
      cursor.close();
    }
    return result;
  }

  @Override
  public void shutdown() {
  }
}
