/*
 * Copyright (C) 2010 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;

import com.android.ide.common.rendering.api.LayoutLog;
import com.android.layoutlib.bridge.Bridge;
import com.android.layoutlib.bridge.impl.DelegateManager;
import com.android.ninepatch.NinePatchChunk;
import com.android.tools.layoutlib.annotations.LayoutlibDelegate;

import android.graphics.drawable.NinePatchDrawable;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.ref.SoftReference;
import java.util.HashMap;
import java.util.Map;

/**
 * Delegate implementing the native methods of android.graphics.NinePatch
 *
 * Through the layoutlib_create tool, the original native methods of NinePatch have been replaced
 * by calls to methods of the same name in this delegate class.
 *
 * Because it's a stateless class to start with, there's no need to keep a {@link DelegateManager}
 * around to map int to instance of the delegate.
 *
 */
public final class NinePatch_Delegate {

    // ---- delegate manager ----
    private static final DelegateManager<NinePatch_Delegate> sManager =
            new DelegateManager<>(NinePatch_Delegate.class);

    // ---- delegate helper data ----
    /**
     * Cache map for {@link NinePatchChunk}.
     * When the chunks are created they are serialized into a byte[], and both are put
     * in the cache, using a {@link SoftReference} for the chunk. The default Java classes
     * for {@link NinePatch} and {@link NinePatchDrawable} only reference to the byte[] data, and
     * provide this for drawing.
     * Using the cache map allows us to not have to deserialize the byte[] back into a
     * {@link NinePatchChunk} every time a rendering is done.
     */
    private final static Map<byte[], SoftReference<NinePatchChunk>> sChunkCache = new HashMap<>();

    // ---- delegate data ----
    private byte[] chunk;


    // ---- Public Helper methods ----

    /**
     * Serializes the given chunk.
     *
     * @return the serialized data for the chunk.
     */
    public static byte[] serialize(NinePatchChunk chunk) {
        // serialize the chunk to get a byte[]
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ObjectOutputStream oos = null;
        try {
            oos = new ObjectOutputStream(baos);
            oos.writeObject(chunk);
        } catch (IOException e) {
            Bridge.getLog().error(null, "Failed to serialize NinePatchChunk.", e, null /*data*/);
            return null;
        } finally {
            if (oos != null) {
                try {
                    oos.close();
                } catch (IOException ignored) {
                }
            }
        }

        // get the array and add it to the cache
        byte[] array = baos.toByteArray();
        sChunkCache.put(array, new SoftReference<>(chunk));
        return array;
    }

    /**
     * Returns a {@link NinePatchChunk} object for the given serialized representation.
     *
     * If the chunk is present in the cache then the object from the cache is returned, otherwise
     * the array is deserialized into a {@link NinePatchChunk} object.
     *
     * @param array the serialized representation of the chunk.
     * @return the NinePatchChunk or null if deserialization failed.
     */
    public static NinePatchChunk getChunk(byte[] array) {
        SoftReference<NinePatchChunk> chunkRef = sChunkCache.get(array);
        NinePatchChunk chunk = chunkRef == null ? null : chunkRef.get();
        if (chunk == null) {
            ByteArrayInputStream bais = new ByteArrayInputStream(array);
            try (ObjectInputStream ois = new ObjectInputStream(bais)) {
                chunk = (NinePatchChunk) ois.readObject();

                // put back the chunk in the cache
                if (chunk != null) {
                    sChunkCache.put(array, new SoftReference<>(chunk));
                }
            } catch (IOException e) {
                Bridge.getLog().error(LayoutLog.TAG_BROKEN,
                        "Failed to deserialize NinePatchChunk content.", e, null /*data*/);
                return null;
            } catch (ClassNotFoundException e) {
                Bridge.getLog().error(LayoutLog.TAG_BROKEN,
                        "Failed to deserialize NinePatchChunk class.", e, null /*data*/);
                return null;
            }
        }

        return chunk;
    }

    // ---- native methods ----

    @LayoutlibDelegate
    /*package*/ static boolean isNinePatchChunk(byte[] chunk) {
        NinePatchChunk chunkObject = getChunk(chunk);
        return chunkObject != null;
    }

    @LayoutlibDelegate
    /*package*/ static long validateNinePatchChunk(byte[] chunk) {
        // the default JNI implementation only checks that the byte[] has the same
        // size as the C struct it represent. Since we cannot do the same check (serialization
        // will return different size depending on content), we do nothing.
        NinePatch_Delegate newDelegate = new NinePatch_Delegate();
        newDelegate.chunk = chunk;
        return sManager.addNewDelegate(newDelegate);
    }

    @LayoutlibDelegate
    /*package*/ static void nativeFinalize(long nativeNinePatch) {
        NinePatch_Delegate delegate = sManager.getDelegate(nativeNinePatch);
        if (delegate != null && delegate.chunk != null) {
            sChunkCache.remove(delegate.chunk);
        }
        sManager.removeJavaReferenceFor(nativeNinePatch);
    }


    @LayoutlibDelegate
    /*package*/ static long nativeGetTransparentRegion(long bitmapHandle, long chunk,
            Rect location) {
        return 0;
    }

    static byte[] getChunk(long nativeNinePatch) {
        NinePatch_Delegate delegate = sManager.getDelegate(nativeNinePatch);
        if (delegate != null) {
            return delegate.chunk;
        }
        return null;
    }

    public static void clearCache() {
        sChunkCache.clear();
    }
}
