content: /*
    * CDDL HEADER START
   *
   * The contents of this file are subject to the terms of the Common Development
   * and Distribution License (the "License").
   * You may not use this file except in compliance with the License.
   *
   * You can obtain a copy of the license at
   * src/com/vodafone360/people/VODAFONE.LICENSE.txt or
   * http://github.com/360/360-Engine-for-Android
   * See the License for the specific language governing permissions and
   * limitations under the License.
   *
   * When distributing Covered Code, include this CDDL HEADER in each file and
   * include the License file at src/com/vodafone360/people/VODAFONE.LICENSE.txt.
   * If applicable, add the following below this CDDL HEADER, with the fields
   * enclosed by brackets "[]" replaced with your own identifying information:
   * Portions Copyright [yyyy] [name of copyright owner]
   *
   * CDDL HEADER END
   *
   * Copyright 2010 Vodafone Sales & Services Ltd.  All rights reserved.
   * Use is subject to license terms.
   */
  
  package com.vodafone360.people.engine.presence;
  
  import java.text.DateFormat;
  import java.util.ArrayList;
  import java.util.Date;
  import java.util.List;
  
  import android.database.sqlite.SQLiteDatabase;
  
  import com.vodafone360.people.database.DatabaseHelper;
  import com.vodafone360.people.database.tables.ActivitiesTable;
  import com.vodafone360.people.database.tables.ContactDetailsTable;
  import com.vodafone360.people.database.tables.ContactSummaryTable;
  import com.vodafone360.people.database.tables.ConversationsTable;
  import com.vodafone360.people.database.tables.ActivitiesTable.TimelineNativeTypes;
  import com.vodafone360.people.database.tables.ActivitiesTable.TimelineSummaryItem;
  import com.vodafone360.people.datatypes.ActivityItem;
  import com.vodafone360.people.datatypes.ChatMessage;
  import com.vodafone360.people.datatypes.ContactDetail;
  import com.vodafone360.people.datatypes.ContactSummary;
  import com.vodafone360.people.datatypes.VCardHelper;
  import com.vodafone360.people.datatypes.ContactDetail.DetailKeys;
  import com.vodafone360.people.engine.presence.NetworkPresence.SocialNetwork;
  import com.vodafone360.people.service.ServiceStatus;
  import com.vodafone360.people.utils.LogUtils;
  
  /***
   * Utilities relating to Chat messages.
   */
  public class ChatDbUtils {
  
      /**
       * User ID is formated <network>::<userId>, using this as the divider.
       */
      protected static final String COLUMNS = "::";
  
      /***
       * Set the user ID, network ID and local contact ID values in the given
       * ChatMessage.
       *
       * The original msg.getUserId() is formatted <network>::<userId>, meaning
       * if "::" is present the values are split, otherwise the original value is
       * used.
       *
       * @param chatMessage ChatMessage to be altered.
       * @param databaseHelper DatabaseHelper with a readable database.
       */
      public static void convertUserIds(final ChatMessage chatMessage,
              final DatabaseHelper databaseHelper) {
  
          /**
           * Use original User ID, in case of NumberFormatException (see
           * PAND-2356).
           */
          final String originalUserId = chatMessage.getUserId();
  
          int index = originalUserId.indexOf(COLUMNS);
          if (index > -1) {
              /** Parse a <networkId>::<userId> formatted user ID. **/
              chatMessage.setUserId(
                      originalUserId.substring(index + COLUMNS.length()));
              String network = originalUserId.substring(0, index);
  
              /** Parse the <networkId> component. **/
              SocialNetwork sn = SocialNetwork.getValue(network);
              if (sn != null) {
                  chatMessage.setNetworkId(sn.ordinal());
              } else {
                  chatMessage.setNetworkId(SocialNetwork.INVALID.ordinal());
                  LogUtils.logE("ChatUtils.convertUserIds() Invalid Network ID ["
                          + network + "] in [" + originalUserId + "]");
              }
          }
  
          chatMessage.setLocalContactId(
                  ContactDetailsTable.findLocalContactIdByKey(
                          SocialNetwork.getSocialNetworkValue(
                                  chatMessage.getNetworkId()).toString(),
                                  chatMessage.getUserId(),
                                  ContactDetail.DetailKeys.VCARD_IMADDRESS,
                                  databaseHelper.getReadableDatabase())
                  );
      }
  
      /**
       * This method saves the supplied
       * 
       * @param msg
       * @param type
       * @param databaseHelper
       */
      protected static void saveChatMessageAsATimeline(ChatMessage message,
              TimelineSummaryItem.Type type, DatabaseHelper databaseHelper) {
          TimelineSummaryItem item = new TimelineSummaryItem();
          fillInContactDetails(message, item, databaseHelper, type);
          SQLiteDatabase writableDatabase = databaseHelper.getWritableDatabase();
          
          boolean isRead = true;
          if(type == TimelineSummaryItem.Type.INCOMING) {
              isRead = false;
          }
          
          if (ActivitiesTable.addChatTimelineEvent(item,
                  isRead,
                  writableDatabase) != -1) {
              ConversationsTable.addNewConversationId(message, writableDatabase);
          } else {
              LogUtils.logE("The msg was not saved to the ActivitiesTable");
          }
      }
  
      /**
       * Remove hard code
       * 
       * @param msg
       * @param item
       * @param databaseHelper
       * @param incoming
       */
      private static void fillInContactDetails(ChatMessage msg, TimelineSummaryItem item,
              DatabaseHelper databaseHelper, TimelineSummaryItem.Type incoming) {
          item.mTimestamp = System.currentTimeMillis();
  //        here we set the time stamp back into the chat message 
  //        in order to be able to remove it from the chat history by time stamp in case its delivery fails
          msg.setTimeStamp(item.mTimestamp);
          
          item.mType = ActivityItem.Type.MESSAGE_IM_CONVERSATION;
          item.mDescription = msg.getBody();
          item.mTitle = DateFormat.getDateInstance().format(new Date(item.mTimestamp));
  
          // we store sender's localContactId for incoming msgs and recipient's
          // localContactId for outgoing msgs
          item.mLocalContactId = msg.getLocalContactId();
          if (item.mLocalContactId != null && item.mLocalContactId != -1) {
              ContactDetail cd = ContactDetailsTable.fetchDetail(item.mLocalContactId,
                      DetailKeys.VCARD_NAME, databaseHelper.getReadableDatabase());
              if (cd == null || cd.getName() == null) {
                  // if we don't get any details, we have to check the summary
                  // table because gtalk contacts
                  // without name will be otherwise show as unknown
                  ContactSummary contactSummary = new ContactSummary();
                  ServiceStatus error = ContactSummaryTable.fetchSummaryItem(item.mLocalContactId,
                          contactSummary, databaseHelper.getReadableDatabase());
                  if (error == ServiceStatus.SUCCESS) {
                      item.mContactName = (contactSummary.formattedName != null) ? contactSummary.formattedName
                              : ContactDetail.UNKNOWN_NAME;
                  } else {
                      item.mContactName = ContactDetail.UNKNOWN_NAME;
                  }
              } else {
                  /** Get name from contact details. **/
                  VCardHelper.Name name = cd.getName();
                  item.mContactName = (name != null) ? name.toString() : ContactDetail.UNKNOWN_NAME;
              }
          }
          item.mIncoming = incoming;
          item.mContactNetwork = SocialNetwork.getSocialNetworkValue(msg.getNetworkId()).toString();
          item.mNativeItemType = TimelineNativeTypes.ChatLog.ordinal();
      }
  
  
      /**
       * This method copies the conversation id and user id into the supplied
       * ChatMessage based on its mNetworkId and mLocalContactId
       * 
       * @param chatMessage ChatMessage
       * @param databaseHelper Databasehelper
       */
      protected static void fillMessageByLocalContactIdAndNetworkId(ChatMessage chatMessage,
              DatabaseHelper databaseHelper) {
          ConversationsTable.fillMessageInByLocalContactIdAndNetworkId(chatMessage, databaseHelper
                  .getReadableDatabase(), databaseHelper.getWritableDatabase());
      }
  
      /**
       * This method finds the user id (360 UserId or 3rd-party network id) and
       * sets it into the supplied chat message
       * 
       * @param msg ChatMessage - the supplied chat message
       * @param databaseHelper DatabaseHelper - the database
       */
      protected static void findUserIdForMessageByLocalContactIdAndNetworkId(ChatMessage msg,
              DatabaseHelper databaseHelper) {
          List<String> tos = new ArrayList<String>();
          msg.setUserId(ContactDetailsTable.findChatIdByLocalContactIdAndNetwork(SocialNetwork
                  .getSocialNetworkValue(msg.getNetworkId()).toString(), msg.getLocalContactId(),
                  databaseHelper.getReadableDatabase()));
          String fullUserId = SocialNetwork.getSocialNetworkValue(msg.getNetworkId()).toString() + COLUMNS
                  + msg.getUserId();
          tos.add(fullUserId);
          msg.setUserId(fullUserId);
          msg.setTos(tos);
      }
  
      /**
       * This method deletes the conversation with the given id from the
       * ConversationsTable
       * 
       * @param conversationId String - the conversation id
       * @param dbHelper DatabaseHelper - the database
       */
      protected static void deleteConversationById(String conversationId, DatabaseHelper dbHelper) {
          ConversationsTable.removeConversation(conversationId, dbHelper.getWritableDatabase());
      }
  
      /**
       * This method deletes conversations older than 1 week except for those with
       * current contact
       * 
       * @param localContactId long- current contact mLocalContactId
       * @param dbHelper DatabaseHelper - the database
       */
      protected static void cleanOldConversationsExceptForContact(long localContactId,
              DatabaseHelper dbHelper) {
          ActivitiesTable.removeChatTimelineExceptForContact(localContactId, dbHelper
                  .getWritableDatabase());
      }
  
      /**
       * This method returns the number of unread chat messages for this contact
       * 
       * @param localContactId long - the contact's mLocalContactId
       * @param network String - the specified network, @see SocialNetwork
       * @param dbHelper Database - the database
       * @return int - the number of unread chat messages for the specified
       *         contact
       */
      public static int getNumberOfUnreadChatMessagesForContactAndNetwork(long localContactId,
              String network, DatabaseHelper dbHelper) {
          return ActivitiesTable.getNumberOfUnreadChatMessagesForContactAndNetwork(localContactId,
                  network, dbHelper.getReadableDatabase());
      }
  
      /**
       * This method deletes the last outgoing chat message in
       * ActivitiesTable, and removes the conversation id of this message from the
       * ConversationsTable. So that next time when user tries to send a message a
       * new conversation id will be requested. The message sending might fail
       * because the conversation id might have expired. 
       * 
       * Currently there's no reliable way to get the reason of message delivery failure, so
       * we assume that an expired conversation id might cause it as well, and remove it.
       *
       * In case the conversation id is valid the "get conversation" call will return the old id.
       * 
       * @param dbHelper DatabaseHelper - database
       * @param message ChatMessage - the chat message which has not been sent and needs to be deleted from the history.
       */
     protected static void deleteUnsentMessage(DatabaseHelper dbHelper, ChatMessage message) {
          ConversationsTable.removeConversation(message.getConversationId(), dbHelper.getWritableDatabase());
          ActivitiesTable.deleteUnsentChatMessageForContact(message.getLocalContactId(), message.getTimeStamp(), dbHelper.getWritableDatabase());
      }
  }
  