/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 */
package com.android.dialer.calllog.ui;

import android.content.Context;
import android.net.Uri;
import android.provider.CallLog.Calls;
import android.support.v4.content.CursorLoader;
import com.android.dialer.calllog.database.contract.AnnotatedCallLogContract.AnnotatedCallLog;

/** Bounded, keyset-paged cursor loader for the annotated call log. */
final class AnnotatedCallLogCursorLoader extends CursorLoader {

  static final int FILTER_ALL = 0;
  static final int FILTER_MISSED = 1;
  static final int PAGE_SIZE = 250;

  AnnotatedCallLogCursorLoader(
      Context context, int filter, long beforeTimestamp, long beforeId) {
    super(
        context,
        pagedUri(),
        /* projection = */ null,
        selection(filter, beforeTimestamp),
        selectionArgs(filter, beforeTimestamp, beforeId),
        AnnotatedCallLog.TIMESTAMP + " DESC, " + AnnotatedCallLog._ID + " DESC");
  }

  private static Uri pagedUri() {
    return AnnotatedCallLog.CONTENT_URI
        .buildUpon()
        .appendQueryParameter("limit", Integer.toString(PAGE_SIZE))
        .build();
  }

  private static String selection(int filter, long beforeTimestamp) {
    StringBuilder out = new StringBuilder();

    // Voicemail has its own surface and should not be mixed into the regular call history.
    out.append(AnnotatedCallLog.CALL_TYPE).append(" != ?");

    if (filter == FILTER_MISSED) {
      out.append(" AND ").append(AnnotatedCallLog.CALL_TYPE).append(" = ?");
    }

    if (beforeTimestamp != Long.MAX_VALUE) {
      out.append(" AND (")
          .append(AnnotatedCallLog.TIMESTAMP).append(" < ? OR (")
          .append(AnnotatedCallLog.TIMESTAMP).append(" = ? AND ")
          .append(AnnotatedCallLog._ID).append(" < ?))");
    }
    return out.toString();
  }

  private static String[] selectionArgs(int filter, long beforeTimestamp, long beforeId) {
    java.util.ArrayList<String> args = new java.util.ArrayList<>();
    args.add(Integer.toString(Calls.VOICEMAIL_TYPE));

    if (filter == FILTER_MISSED) {
      args.add(Integer.toString(Calls.MISSED_TYPE));
    }

    if (beforeTimestamp != Long.MAX_VALUE) {
      args.add(Long.toString(beforeTimestamp));
      args.add(Long.toString(beforeTimestamp));
      args.add(Long.toString(beforeId));
    }
    return args.toArray(new String[0]);
  }
}
