/*
 * 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.Handler;
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, @NonNull Handler handler,
            boolean bindInstantServiceAllowed, boolean verbose, int initialCapacity) {
        super(context, serviceInterface, componentName, userId, callback, handler,
                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);
        }
    }
}
