/*
 * 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.graphics.pdf;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.graphics.Matrix;
import android.graphics.Point;
import android.graphics.Rect;
import android.os.ParcelFileDescriptor;
import android.system.ErrnoException;
import android.system.OsConstants;
import dalvik.system.CloseGuard;
import libcore.io.IoUtils;
import libcore.io.Libcore;

import java.io.IOException;

/**
 * Class for editing PDF files.
 *
 * @hide
 */
public final class PdfEditor {

    private final CloseGuard mCloseGuard = CloseGuard.get();

    private final long mNativeDocument;

    private int mPageCount;

    private ParcelFileDescriptor mInput;

    /**
     * Creates a new instance.
     * <p>
     * <strong>Note:</strong> The provided file descriptor must be <strong>seekable</strong>,
     * i.e. its data being randomly accessed, e.g. pointing to a file. After finishing
     * with this class you must call {@link #close()}.
     * </p>
     * <p>
     * <strong>Note:</strong> This class takes ownership of the passed in file descriptor
     * and is responsible for closing it when the editor is closed.
     * </p>
     *
     * @param input Seekable file descriptor to read from.
     *
     * @throws java.io.IOException If an error occurs while reading the file.
     * @throws java.lang.SecurityException If the file requires a password or
     *         the security scheme is not supported.
     *
     * @see #close()
     */
    public PdfEditor(@NonNull ParcelFileDescriptor input) throws IOException {
        if (input == null) {
            throw new NullPointerException("input cannot be null");
        }

        final long size;
        try {
            Libcore.os.lseek(input.getFileDescriptor(), 0, OsConstants.SEEK_SET);
            size = Libcore.os.fstat(input.getFileDescriptor()).st_size;
        } catch (ErrnoException ee) {
            throw new IllegalArgumentException("file descriptor not seekable");
        }

        mInput = input;
        mNativeDocument = nativeOpen(mInput.getFd(), size);
        mPageCount = nativeGetPageCount(mNativeDocument);
        mCloseGuard.open("close");
    }

    /**
     * Gets the number of pages in the document.
     *
     * @return The page count.
     */
    public int getPageCount() {
        throwIfClosed();
        return mPageCount;
    }

    /**
     * Removes the page with a given index.
     *
     * @param pageIndex The page to remove.
     */
    public void removePage(int pageIndex) {
        throwIfClosed();
        throwIfPageNotInDocument(pageIndex);
        mPageCount = nativeRemovePage(mNativeDocument, pageIndex);
    }

    /**
     * Sets a transformation and clip for a given page. The transformation matrix if
     * non-null must be affine as per {@link android.graphics.Matrix#isAffine()}. If
     * the clip is null, then no clipping is performed.
     *
     * @param pageIndex The page whose transform to set.
     * @param transform The transformation to apply.
     * @param clip The clip to apply.
     */
    public void setTransformAndClip(int pageIndex, @Nullable Matrix transform,
            @Nullable Rect clip) {
        throwIfClosed();
        throwIfPageNotInDocument(pageIndex);
        throwIfNotNullAndNotAfine(transform);
        if (transform == null) {
            transform = Matrix.IDENTITY_MATRIX;
        }
        if (clip == null) {
            Point size = new Point();
            getPageSize(pageIndex, size);
            nativeSetTransformAndClip(mNativeDocument, pageIndex, transform.native_instance,
                    0, 0, size.x, size.y);
        } else {
            nativeSetTransformAndClip(mNativeDocument, pageIndex, transform.native_instance,
                    clip.left, clip.top, clip.right, clip.bottom);
        }
    }

    /**
     * Gets the size of a given page in mils (1/72").
     *
     * @param pageIndex The page index.
     * @param outSize The size output.
     */
    public void getPageSize(int pageIndex, @NonNull Point outSize) {
        throwIfClosed();
        throwIfOutSizeNull(outSize);
        throwIfPageNotInDocument(pageIndex);
        nativeGetPageSize(mNativeDocument, pageIndex, outSize);
    }

    /**
     * Gets the media box of a given page in mils (1/72").
     *
     * @param pageIndex The page index.
     * @param outMediaBox The media box output.
     */
    public boolean getPageMediaBox(int pageIndex, @NonNull Rect outMediaBox) {
        throwIfClosed();
        throwIfOutMediaBoxNull(outMediaBox);
        throwIfPageNotInDocument(pageIndex);
        return nativeGetPageMediaBox(mNativeDocument, pageIndex, outMediaBox);
    }

    /**
     * Sets the media box of a given page in mils (1/72").
     *
     * @param pageIndex The page index.
     * @param mediaBox The media box.
     */
    public void setPageMediaBox(int pageIndex, @NonNull Rect mediaBox) {
        throwIfClosed();
        throwIfMediaBoxNull(mediaBox);
        throwIfPageNotInDocument(pageIndex);
        nativeSetPageMediaBox(mNativeDocument, pageIndex, mediaBox);
    }

    /**
     * Gets the crop box of a given page in mils (1/72").
     *
     * @param pageIndex The page index.
     * @param outCropBox The crop box output.
     */
    public boolean getPageCropBox(int pageIndex, @NonNull Rect outCropBox) {
        throwIfClosed();
        throwIfOutCropBoxNull(outCropBox);
        throwIfPageNotInDocument(pageIndex);
        return nativeGetPageCropBox(mNativeDocument, pageIndex, outCropBox);
    }

    /**
     * Sets the crop box of a given page in mils (1/72").
     *
     * @param pageIndex The page index.
     * @param cropBox The crop box.
     */
    public void setPageCropBox(int pageIndex, @NonNull Rect cropBox) {
        throwIfClosed();
        throwIfCropBoxNull(cropBox);
        throwIfPageNotInDocument(pageIndex);
        nativeSetPageCropBox(mNativeDocument, pageIndex, cropBox);
    }

    /**
     * Gets whether the document prefers to be scaled for printing.
     *
     * @return Whether to scale the document.
     */
    public boolean shouldScaleForPrinting() {
        throwIfClosed();
        return nativeScaleForPrinting(mNativeDocument);
    }

    /**
     * Writes the PDF file to the provided destination.
     * <p>
     * <strong>Note:</strong> This method takes ownership of the passed in file
     * descriptor and is responsible for closing it when writing completes.
     * </p>
     * @param output The destination.
     */
    public void write(ParcelFileDescriptor output) throws IOException {
        try {
            throwIfClosed();
            nativeWrite(mNativeDocument, output.getFd());
        } finally {
            IoUtils.closeQuietly(output);
        }
    }

    /**
     * Closes this editor. You should not use this instance
     * after this method is called.
     */
    public void close() {
        throwIfClosed();
        doClose();
    }

    @Override
    protected void finalize() throws Throwable {
        try {
            mCloseGuard.warnIfOpen();
            if (mInput != null) {
                doClose();
            }
        } finally {
            super.finalize();
        }
    }

    private void doClose() {
        nativeClose(mNativeDocument);
        IoUtils.closeQuietly(mInput);
        mInput = null;
        mCloseGuard.close();
    }

    private void throwIfClosed() {
        if (mInput == null) {
            throw new IllegalStateException("Already closed");
        }
    }

    private void throwIfPageNotInDocument(int pageIndex) {
        if (pageIndex < 0 || pageIndex >= mPageCount) {
            throw new IllegalArgumentException("Invalid page index");
        }
    }

    private void throwIfNotNullAndNotAfine(Matrix matrix) {
        if (matrix != null && !matrix.isAffine()) {
            throw new IllegalStateException("Matrix must be afine");
        }
    }

    private void throwIfOutSizeNull(Point outSize) {
        if (outSize == null) {
            throw new NullPointerException("outSize cannot be null");
        }
    }

    private void throwIfOutMediaBoxNull(Rect outMediaBox) {
        if (outMediaBox == null) {
            throw new NullPointerException("outMediaBox cannot be null");
        }
    }

    private void throwIfMediaBoxNull(Rect mediaBox) {
        if (mediaBox == null) {
            throw new NullPointerException("mediaBox cannot be null");
        }
    }

    private void throwIfOutCropBoxNull(Rect outCropBox) {
        if (outCropBox == null) {
            throw new NullPointerException("outCropBox cannot be null");
        }
    }

    private void throwIfCropBoxNull(Rect cropBox) {
        if (cropBox == null) {
            throw new NullPointerException("cropBox cannot be null");
        }
    }

    private static native long nativeOpen(int fd, long size);
    private static native void nativeClose(long documentPtr);
    private static native int nativeGetPageCount(long documentPtr);
    private static native int nativeRemovePage(long documentPtr, int pageIndex);
    private static native void nativeWrite(long documentPtr, int fd);
    private static native void nativeSetTransformAndClip(long documentPtr, int pageIndex,
            long transformPtr, int clipLeft, int clipTop, int clipRight, int clipBottom);
    private static native void nativeGetPageSize(long documentPtr, int pageIndex, Point outSize);
    private static native boolean nativeGetPageMediaBox(long documentPtr, int pageIndex,
            Rect outMediaBox);
    private static native void nativeSetPageMediaBox(long documentPtr, int pageIndex,
            Rect mediaBox);
    private static native boolean nativeGetPageCropBox(long documentPtr, int pageIndex,
            Rect outMediaBox);
    private static native void nativeSetPageCropBox(long documentPtr, int pageIndex,
            Rect mediaBox);
    private static native boolean nativeScaleForPrinting(long documentPtr);
}
