/*
 * Copyright (C) 2018 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.android.internal.infra;

import android.annotation.NonNull;
import android.content.ComponentName;
import android.content.Context;
import android.os.IInterface;
import android.util.Slog;

import java.io.PrintWriter;
import java.util.ArrayList;

/**
 * Base class representing a remote service that can queue multiple pending requests while not
 * bound.
 *
 * @param <S> the concrete remote service class
 * @param <I> the interface of the binder service
 * @hide
 */
public abstract class AbstractMultiplePendingRequestsRemoteService<S
        extends AbstractMultiplePendingRequestsRemoteService<S, I>, I extends IInterface>
        extends AbstractRemoteService<S, I> {

    private final int mInitialCapacity;

    protected ArrayList<BasePendingRequest<S, I>> mPendingRequests;

    public AbstractMultiplePendingRequestsRemoteService(@NonNull Context context,
            @NonNull String serviceInterface, @NonNull ComponentName componentName, int userId,
            @NonNull VultureCallback<S> callback, boolean bindInstantServiceAllowed,
            boolean verbose, int initialCapacity) {
        super(context, serviceInterface, componentName, userId, callback, bindInstantServiceAllowed,
                verbose);
        mInitialCapacity = initialCapacity;
    }

    @Override // from AbstractRemoteService
    void handlePendingRequests() {
        if (mPendingRequests != null) {
            final int size = mPendingRequests.size();
            if (mVerbose) Slog.v(mTag, "Sending " + size + " pending requests");
            for (int i = 0; i < size; i++) {
                mPendingRequests.get(i).run();
            }
            mPendingRequests = null;
        }
    }

    @Override // from AbstractRemoteService
    protected void handleOnDestroy() {
        if (mPendingRequests != null) {
            final int size = mPendingRequests.size();
            if (mVerbose) Slog.v(mTag, "Canceling " + size + " pending requests");
            for (int i = 0; i < size; i++) {
                mPendingRequests.get(i).cancel();
            }
            mPendingRequests = null;
        }
    }

    @Override // from AbstractRemoteService
    public void dump(@NonNull String prefix, @NonNull PrintWriter pw) {
        super.dump(prefix, pw);

        pw.append(prefix).append("initialCapacity=").append(String.valueOf(mInitialCapacity))
                .println();
        final int size = mPendingRequests == null ? 0 : mPendingRequests.size();
        pw.append(prefix).append("pendingRequests=").append(String.valueOf(size)).println();
    }

    @Override // from AbstractRemoteService
    void handlePendingRequestWhileUnBound(@NonNull BasePendingRequest<S, I> pendingRequest) {
        if (mPendingRequests == null) {
            mPendingRequests = new ArrayList<>(mInitialCapacity);
        }
        mPendingRequests.add(pendingRequest);
        if (mVerbose) {
            Slog.v(mTag, "queued " + mPendingRequests.size() + " requests; last=" + pendingRequest);
        }
    }
}
