/*
 * Copyright (C) 2025 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.google.snippet.telecom;

import android.content.Context;
import android.content.Intent;
import android.telecom.Call;
import android.telecom.InCallService;
import android.telephony.PhoneNumberUtils;
import androidx.annotation.Nullable;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import androidx.test.platform.app.InstrumentationRegistry;
import com.google.android.mobly.snippet.event.EventCache;
import com.google.android.mobly.snippet.event.SnippetEvent;
import java.util.ArrayList;
import java.util.List;

/**
 * InCallService implementation for Mobly Snippet.
 *
 * <p>Suppressing deprecation for LocalBroadcastManager since this usage is retained due to legacy
 * project constraints. Will consider migrating to AndroidX and replacing to {@link
 * androidx.lifecycle.LiveData} when feasible.
 */
@SuppressWarnings("deprecation")
public class InCallServiceImpl extends InCallService {
  public static final String CALLBACK_ID = "IN_CALL_SERVICE_SNIPPET_EVENT_CALLBACK_ID";
  public static final String CALLBACK_KEY = "IN_CALL_SERVICE_SNIPPET_EVENT_CALLBACK_KEY";

  private static final Context context = InstrumentationRegistry.getInstrumentation().getContext();
  private static final List<Call> activeCalls = new ArrayList<>();

  private EventCache eventCache;

  public InCallServiceImpl() {
    eventCache = EventCache.getInstance();
  }

  private void startInCallActivity() {
    Intent intent = new Intent();
    intent.setClass(this, InCallActivity.class);
    intent.setFlags(Intent.FLAG_ACTIVITY_NO_USER_ACTION | Intent.FLAG_ACTIVITY_NEW_TASK);
    this.startActivity(intent);
  }

  private void finishInCallActivity() {
    Intent intent = new Intent(InCallActivity.ACTION_FINISH_INCALLACTIVITY);
    LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
  }

  @Override
  public void onCallAdded(Call call) {
    super.onCallAdded(call);
    activeCalls.add(call);
    startInCallActivity();

    call.registerCallback(
        new Call.Callback() {
          @Override
          public void onStateChanged(Call call, int state) {
            SnippetEvent event = new SnippetEvent(CALLBACK_ID, CALLBACK_KEY);
            event.getData().putInt("state", state);
            event
                .getData()
                .putString("phoneNumber", call.getDetails().getHandle().getSchemeSpecificPart());
            eventCache.postEvent(event);
          }
        });
  }

  @Override
  public void onCallRemoved(Call call) {
    super.onCallRemoved(call);
    activeCalls.remove(call);
    finishInCallActivity();
  }

  @Override
  public void onBringToForeground(boolean showDialpad) {
    startInCallActivity();
  }

  public static List<Call> getActiveCalls() {
    return activeCalls;
  }

  @Nullable
  public static Call getCallByPhoneNumber(String phoneNumber) {
    for (Call call : activeCalls) {
      if (arePhoneNumbersEqual(
          call.getDetails().getHandle().getSchemeSpecificPart(), phoneNumber)) {
        return call;
      }
    }
    return null;
  }

  public static boolean arePhoneNumbersEqual(String phoneNumber1, String phoneNumber2) {
    return PhoneNumberUtils.compare(context, phoneNumber1, phoneNumber2);
  }
}

