/*
 * Copyright (C) 2014 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 android.hardware.camera2.legacy;

import android.hardware.camera2.CaptureRequest;
import android.util.Log;
import android.view.Surface;

import java.util.Collection;

import static com.android.internal.util.Preconditions.*;

/**
 * Semi-immutable container for a single capture request and associated information,
 * the only mutable characteristic of this container is whether or not is has been
 * marked as "failed" using {@code #failRequest}.
 */
public class RequestHolder {
    private static final String TAG = "RequestHolder";

    private final boolean mRepeating;
    private final CaptureRequest mRequest;
    private final int mRequestId;
    private final int mSubsequeceId;
    private final long mFrameNumber;
    private final int mNumJpegTargets;
    private final int mNumPreviewTargets;
    private volatile boolean mFailed = false;
    private boolean mOutputAbandoned = false;

    private final Collection<Long> mJpegSurfaceIds;

    /**
     * A builder class for {@link RequestHolder} objects.
     *
     * <p>
     * This allows per-request queries to be cached for repeating {@link CaptureRequest} objects.
     * </p>
     */
    public final static class Builder {
        private final int mRequestId;
        private final int mSubsequenceId;
        private final CaptureRequest mRequest;
        private final boolean mRepeating;
        private final int mNumJpegTargets;
        private final int mNumPreviewTargets;
        private final Collection<Long> mJpegSurfaceIds;

        /**
         * Construct a new {@link Builder} to generate {@link RequestHolder} objects.
         *
         * @param requestId the ID to set in {@link RequestHolder} objects.
         * @param subsequenceId the sequence ID to set in {@link RequestHolder} objects.
         * @param request the original {@link CaptureRequest} to set in {@link RequestHolder}
         *                objects.
         * @param repeating {@code true} if the request is repeating.
         */
        public Builder(int requestId, int subsequenceId, CaptureRequest request,
                       boolean repeating, Collection<Long> jpegSurfaceIds) {
            checkNotNull(request, "request must not be null");
            mRequestId = requestId;
            mSubsequenceId = subsequenceId;
            mRequest = request;
            mRepeating = repeating;
            mJpegSurfaceIds = jpegSurfaceIds;
            mNumJpegTargets = numJpegTargets(mRequest);
            mNumPreviewTargets = numPreviewTargets(mRequest);
        }

        /**
         * Returns true if the given surface requires jpeg buffers.
         *
         * @param s a {@link android.view.Surface} to check.
         * @return true if the surface requires a jpeg buffer.
         */
        private boolean jpegType(Surface s)
                throws LegacyExceptionUtils.BufferQueueAbandonedException {
            return LegacyCameraDevice.containsSurfaceId(s, mJpegSurfaceIds);
        }

        /**
         * Returns true if the given surface requires non-jpeg buffer types.
         *
         * <p>
         * "Jpeg buffer" refers to the buffers returned in the jpeg
         * {@link android.hardware.Camera.PictureCallback}.  Non-jpeg buffers are created using a tee
         * of the preview stream drawn to the surface
         * set via {@link android.hardware.Camera#setPreviewDisplay(android.view.SurfaceHolder)} or
         * equivalent methods.
         * </p>
         * @param s a {@link android.view.Surface} to check.
         * @return true if the surface requires a non-jpeg buffer type.
         */
        private boolean previewType(Surface s)
                throws LegacyExceptionUtils.BufferQueueAbandonedException {
            return !jpegType(s);
        }

        /**
         * Returns the number of surfaces targeted by the request that require jpeg buffers.
         */
        private int numJpegTargets(CaptureRequest request) {
            int count = 0;
            for (Surface s : request.getTargets()) {
                try {
                    if (jpegType(s)) {
                        ++count;
                    }
                } catch (LegacyExceptionUtils.BufferQueueAbandonedException e) {
                    Log.d(TAG, "Surface abandoned, skipping...", e);
                }
            }
            return count;
        }

        /**
         * Returns the number of surfaces targeted by the request that require non-jpeg buffers.
         */
        private int numPreviewTargets(CaptureRequest request) {
            int count = 0;
            for (Surface s : request.getTargets()) {
                try {
                    if (previewType(s)) {
                        ++count;
                    }
                } catch (LegacyExceptionUtils.BufferQueueAbandonedException e) {
                    Log.d(TAG, "Surface abandoned, skipping...", e);
                }
            }
            return count;
        }

        /**
         * Build a new {@link RequestHolder} using with parameters generated from this
         *      {@link Builder}.
         *
         * @param frameNumber the {@code framenumber} to generate in the {@link RequestHolder}.
         * @return a {@link RequestHolder} constructed with the {@link Builder}'s parameters.
         */
        public RequestHolder build(long frameNumber) {
            return new RequestHolder(mRequestId, mSubsequenceId, mRequest, mRepeating, frameNumber,
                    mNumJpegTargets, mNumPreviewTargets, mJpegSurfaceIds);
        }
    }

    private RequestHolder(int requestId, int subsequenceId, CaptureRequest request,
                          boolean repeating, long frameNumber, int numJpegTargets,
                          int numPreviewTargets, Collection<Long> jpegSurfaceIds) {
        mRepeating = repeating;
        mRequest = request;
        mRequestId = requestId;
        mSubsequeceId = subsequenceId;
        mFrameNumber = frameNumber;
        mNumJpegTargets = numJpegTargets;
        mNumPreviewTargets = numPreviewTargets;
        mJpegSurfaceIds = jpegSurfaceIds;
    }

    /**
     * Return the request id for the contained {@link CaptureRequest}.
     */
    public int getRequestId() {
        return mRequestId;
    }

    /**
     * Returns true if the contained request is repeating.
     */
    public boolean isRepeating() {
        return mRepeating;
    }

    /**
     * Return the subsequence id for this request.
     */
    public int getSubsequeceId() {
        return mSubsequeceId;
    }

    /**
     * Returns the frame number for this request.
     */
    public long getFrameNumber() {
        return mFrameNumber;
    }

    /**
     * Returns the contained request.
     */
    public CaptureRequest getRequest() {
        return mRequest;
    }

    /**
     * Returns a read-only collection of the surfaces targeted by the contained request.
     */
    public Collection<Surface> getHolderTargets() {
        return getRequest().getTargets();
    }

    /**
     * Returns true if any of the surfaces targeted by the contained request require jpeg buffers.
     */
    public boolean hasJpegTargets() {
        return mNumJpegTargets > 0;
    }

    /**
     * Returns true if any of the surfaces targeted by the contained request require a
     * non-jpeg buffer type.
     */
    public boolean hasPreviewTargets(){
        return mNumPreviewTargets > 0;
    }

    /**
     * Return the number of jpeg-type surfaces targeted by this request.
     */
    public int numJpegTargets() {
        return mNumJpegTargets;
    }

    /**
     * Return the number of non-jpeg-type surfaces targeted by this request.
     */
    public int numPreviewTargets() {
        return mNumPreviewTargets;
    }

    /**
     * Returns true if the given surface requires jpeg buffers.
     *
     * @param s a {@link android.view.Surface} to check.
     * @return true if the surface requires a jpeg buffer.
     */
    public boolean jpegType(Surface s)
            throws LegacyExceptionUtils.BufferQueueAbandonedException {
        return LegacyCameraDevice.containsSurfaceId(s, mJpegSurfaceIds);
    }

    /**
     * Mark this request as failed.
     */
    public void failRequest() {
        Log.w(TAG, "Capture failed for request: " + getRequestId());
        mFailed = true;
    }

    /**
     * Return {@code true} if this request failed.
     */
    public boolean requestFailed() {
        return mFailed;
    }

    /**
     * Mark at least one of this request's output surfaces is abandoned.
     */
    public void setOutputAbandoned() {
        mOutputAbandoned = true;
    }

    /**
     * Return if any of this request's output surface is abandoned.
     */
    public boolean isOutputAbandoned() {
        return mOutputAbandoned;
    }
}
