package com.android.dialer.calllog.ui;

import android.Manifest.permission;
import android.content.Context;
import android.provider.CallLog.Calls;
import android.support.annotation.Nullable;
import android.support.annotation.RequiresPermission;
import com.android.dialer.CoalescedIds;
import com.android.dialer.common.LogUtil;
import com.android.dialer.common.concurrent.DialerExecutor.Worker;
import com.android.dialer.common.concurrent.DialerExecutorComponent;
import com.android.dialer.logging.DialerImpression;
import com.android.dialer.logging.Logger;

/** Deletes exactly one concrete system call-log record from a displayed history row. */
public final class SingleCallLogDeletion {

  private static final String TAG = "SingleCallLogDeletion";

  private SingleCallLogDeletion() {}

  public static void deleteNewest(
      Context context,
      CoalescedIds coalescedIds,
      Runnable onSuccess,
      Runnable onFailure) {
    if (coalescedIds == null || coalescedIds.getCoalescedIdCount() == 0) {
      if (onFailure != null) {
        onFailure.run();
      }
      return;
    }

    // Coalescer receives rows newest-first, so index 0 is the concrete call represented
    // by the row's timestamp / primary call metadata.
    long callId = coalescedIds.getCoalescedId(0);

    DialerExecutorComponent.get(context)
        .dialerExecutorFactory()
        .createNonUiTaskBuilder(new DeleteOneCallWorker(context.getApplicationContext()))
        .onSuccess(
            deleted -> {
              if (Boolean.TRUE.equals(deleted)) {
                Logger.get(context)
                    .logImpression(DialerImpression.Type.USER_DELETED_CALL_LOG_ITEM);
                if (onSuccess != null) {
                  onSuccess.run();
                }
              } else if (onFailure != null) {
                onFailure.run();
              }
            })
        .onFailure(
            throwable -> {
              LogUtil.e(TAG, "Unable to delete call-log row", throwable);
              if (onFailure != null) {
                onFailure.run();
              }
            })
        .build()
        .executeSerial(callId);
  }

  private static final class DeleteOneCallWorker implements Worker<Long, Boolean> {
    private final Context appContext;

    DeleteOneCallWorker(Context appContext) {
      this.appContext = appContext;
    }

    @Nullable
    @Override
    @RequiresPermission(value = permission.WRITE_CALL_LOG)
    public Boolean doInBackground(@Nullable Long callId) {
      if (callId == null) {
        return false;
      }
      int deleted =
          appContext
              .getContentResolver()
              .delete(
                  Calls.CONTENT_URI,
                  Calls._ID + " = ?",
                  new String[] {Long.toString(callId)});
      if (deleted != 1) {
        LogUtil.e(TAG, "Expected to delete 1 call-log row but deleted %d", deleted);
      }
      return deleted == 1;
    }
  }
}
