/*
 * 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;

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

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.res.AssetManager;
import android.content.res.BridgeAssetManager;
import android.graphics.fonts.FontVariationAxis;

import java.awt.Font;
import java.awt.FontFormatException;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Scanner;
import java.util.Set;
import java.util.logging.Logger;

import libcore.util.NativeAllocationRegistry_Delegate;
import sun.font.FontUtilities;

import static android.graphics.Typeface.RESOLVE_BY_FONT_TABLE;
import static android.graphics.Typeface_Delegate.SYSTEM_FONTS;

/**
 * Delegate implementing the native methods of android.graphics.FontFamily
 *
 * Through the layoutlib_create tool, the original native methods of FontFamily have been replaced
 * by calls to methods of the same name in this delegate class.
 *
 * This class behaves like the original native implementation, but in Java, keeping previously
 * native data into its own objects and mapping them to int that are sent back and forth between
 * it and the original FontFamily class.
 *
 * @see DelegateManager
 */
public class FontFamily_Delegate {

    public static final int DEFAULT_FONT_WEIGHT = 400;
    public static final int BOLD_FONT_WEIGHT_DELTA = 300;
    public static final int BOLD_FONT_WEIGHT = 700;

    private static final String FONT_SUFFIX_ITALIC = "Italic.ttf";
    private static final String FN_ALL_FONTS_LIST = "fontsInSdk.txt";
    private static final String EXTENSION_OTF = ".otf";

    private static final int CACHE_SIZE = 10;
    // The cache has a drawback that if the font file changed after the font object was created,
    // we will not update it.
    private static final Map<String, FontInfo> sCache =
            new LinkedHashMap<String, FontInfo>(CACHE_SIZE) {
        @Override
        protected boolean removeEldestEntry(Map.Entry<String, FontInfo> eldest) {
            return size() > CACHE_SIZE;
        }

        @Override
        public FontInfo put(String key, FontInfo value) {
            // renew this entry.
            FontInfo removed = remove(key);
            super.put(key, value);
            return removed;
        }
    };

    /**
     * A class associating {@link Font} with its metadata.
     */
    public static final class FontInfo {
        @Nullable
        public Font mFont;
        public int mWeight;
        public boolean mIsItalic;

        @Override
        public boolean equals(Object o) {
            if (this == o) {
                return true;
            }
            if (o == null || getClass() != o.getClass()) {
                return false;
            }
            FontInfo fontInfo = (FontInfo) o;
            return mWeight == fontInfo.mWeight && mIsItalic == fontInfo.mIsItalic;
        }

        @Override
        public int hashCode() {
            return Objects.hash(mWeight, mIsItalic);
        }

        @Override
        public String toString() {
            return "FontInfo{" + "mWeight=" + mWeight + ", mIsItalic=" + mIsItalic + '}';
        }
    }

    // ---- delegate manager ----
    private static final DelegateManager<FontFamily_Delegate> sManager =
            new DelegateManager<FontFamily_Delegate>(FontFamily_Delegate.class);
    private static long sFamilyFinalizer = -1;

    // ---- delegate helper data ----
    private static String sFontLocation;
    private static final List<FontFamily_Delegate> sPostInitDelegate = new
            ArrayList<FontFamily_Delegate>();
    private static Set<String> SDK_FONTS;


    // ---- delegate data ----

    // Order does not really matter but we use a LinkedHashMap to get reproducible results across
    // render calls
    private Map<FontInfo, Font> mFonts = new LinkedHashMap<>();

    /**
     * The variant of the Font Family - compact or elegant.
     * <p/>
     * 0 is unspecified, 1 is compact and 2 is elegant. This needs to be kept in sync with values in
     * android.graphics.FontFamily
     *
     * @see Paint#setElegantTextHeight(boolean)
     */
    private FontVariant mVariant;
    // List of runnables to process fonts after sFontLoader is initialized.
    private List<Runnable> mPostInitRunnables = new ArrayList<Runnable>();
    /** @see #isValid() */
    private boolean mValid = false;


    // ---- Public helper class ----

    public enum FontVariant {
        // The order needs to be kept in sync with android.graphics.FontFamily.
        NONE, COMPACT, ELEGANT
    }

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

    public static FontFamily_Delegate getDelegate(long nativeFontFamily) {
        return sManager.getDelegate(nativeFontFamily);
    }

    public static synchronized void setFontLocation(String fontLocation) {
        sFontLocation = fontLocation;
        // init list of bundled fonts.
        File allFonts = new File(fontLocation, FN_ALL_FONTS_LIST);
        // Current number of fonts is 103. Use the next round number to leave scope for more fonts
        // in the future.
        Set<String> allFontsList = new HashSet<>(128);
        Scanner scanner = null;
        try {
            scanner = new Scanner(allFonts);
            while (scanner.hasNext()) {
                String name = scanner.next();
                // Skip font configuration files.
                if (!name.endsWith(".xml")) {
                    allFontsList.add(name);
                }
            }
        } catch (FileNotFoundException e) {
            Bridge.getLog().error(LayoutLog.TAG_BROKEN,
                    "Unable to load the list of fonts. Try re-installing the SDK Platform from the SDK Manager.",
                    e, null);
        } finally {
            if (scanner != null) {
                scanner.close();
            }
        }
        SDK_FONTS = Collections.unmodifiableSet(allFontsList);
        for (FontFamily_Delegate fontFamily : sPostInitDelegate) {
            fontFamily.init();
        }
        sPostInitDelegate.clear();
    }

    @Nullable
    public Font getFont(int desiredWeight, boolean isItalic) {
        FontInfo desiredStyle = new FontInfo();
        desiredStyle.mWeight = desiredWeight;
        desiredStyle.mIsItalic = isItalic;

        Font cachedFont = mFonts.get(desiredStyle);
        if (cachedFont != null) {
            return cachedFont;
        }

        FontInfo bestFont = null;

        if (mFonts.size() == 1) {
            // No need to compute the match since we only have one candidate
            bestFont = mFonts.keySet().iterator().next();
        } else {
            int bestMatch = Integer.MAX_VALUE;

            for (FontInfo font : mFonts.keySet()) {
                int match = computeMatch(font, desiredStyle);
                if (match < bestMatch) {
                    bestMatch = match;
                    bestFont = font;
                    if (bestMatch == 0) {
                        break;
                    }
                }
            }
        }

        if (bestFont == null) {
            return null;
        }


        // Derive the font as required and add it to the list of Fonts.
        deriveFont(bestFont, desiredStyle);
        addFont(desiredStyle);
        return desiredStyle.mFont;
    }

    public FontVariant getVariant() {
        return mVariant;
    }

    /**
     * Returns if the FontFamily should contain any fonts. If this returns true and
     * {@link #getFont(int, boolean)} returns an empty list, it means that an error occurred while
     * loading the fonts. However, some fonts are deliberately skipped, for example they are not
     * bundled with the SDK. In such a case, this method returns false.
     */
    public boolean isValid() {
        return mValid;
    }

    private static Font loadFont(String path) {
        if (path.startsWith(SYSTEM_FONTS) ) {
            String relativePath = path.substring(SYSTEM_FONTS.length());
            File f = new File(sFontLocation, relativePath);

            try {
                return Font.createFont(Font.TRUETYPE_FONT, f);
            } catch (Exception e) {
                if (path.endsWith(EXTENSION_OTF) && e instanceof FontFormatException) {
                    // If we aren't able to load an Open Type font, don't log a warning just yet.
                    // We wait for a case where font is being used. Only then we try to log the
                    // warning.
                    return null;
                }
                Bridge.getLog().fidelityWarning(LayoutLog.TAG_BROKEN,
                        String.format("Unable to load font %1$s", relativePath),
                        e, null);
            }
        } else {
            Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
                    "Only platform fonts located in " + SYSTEM_FONTS + "can be loaded.",
                    null, null);
        }

        return null;
    }

    @Nullable
    public static String getFontLocation() {
        return sFontLocation;
    }

    // ---- delegate methods ----
    @LayoutlibDelegate
    /*package*/ static boolean addFont(FontFamily thisFontFamily, String path, int ttcIndex,
            FontVariationAxis[] axes, int weight, int italic) {
        if (thisFontFamily.mBuilderPtr == 0) {
            assert false : "Unable to call addFont after freezing.";
            return false;
        }
        final FontFamily_Delegate delegate = getDelegate(thisFontFamily.mBuilderPtr);
        return delegate != null && delegate.addFont(path, ttcIndex, weight, italic);
    }

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

    @LayoutlibDelegate
    /*package*/ static long nInitBuilder(String lang, int variant) {
        // TODO: support lang. This is required for japanese locale.
        FontFamily_Delegate delegate = new FontFamily_Delegate();
        // variant can be 0, 1 or 2.
        assert variant < 3;
        delegate.mVariant = FontVariant.values()[variant];
        if (sFontLocation != null) {
            delegate.init();
        } else {
            sPostInitDelegate.add(delegate);
        }
        return sManager.addNewDelegate(delegate);
    }

    @LayoutlibDelegate
    /*package*/ static long nCreateFamily(long builderPtr) {
        return builderPtr;
    }

    @LayoutlibDelegate
    /*package*/ static long nGetFamilyReleaseFunc() {
        synchronized (FontFamily_Delegate.class) {
            if (sFamilyFinalizer == -1) {
                sFamilyFinalizer = NativeAllocationRegistry_Delegate.createFinalizer(
                        sManager::removeJavaReferenceFor);
            }
        }
        return sFamilyFinalizer;
    }

    @LayoutlibDelegate
    /*package*/ static boolean nAddFont(long builderPtr, ByteBuffer font, int ttcIndex,
            int weight, int isItalic) {
        assert false : "The only client of this method has been overridden.";
        return false;
    }

    @LayoutlibDelegate
    /*package*/ static boolean nAddFontWeightStyle(long builderPtr, ByteBuffer font,
            int ttcIndex, int weight, int isItalic) {
        assert false : "The only client of this method has been overridden.";
        return false;
    }

    @LayoutlibDelegate
    /*package*/ static void nAddAxisValue(long builderPtr, int tag, float value) {
        assert false : "The only client of this method has been overridden.";
    }

    static boolean addFont(long builderPtr, final String path, final int weight,
            final boolean isItalic) {
        final FontFamily_Delegate delegate = getDelegate(builderPtr);
        int italic = isItalic ? 1 : 0;
        if (delegate != null) {
            if (sFontLocation == null) {
                delegate.mPostInitRunnables.add(() -> delegate.addFont(path, weight, italic));
                return true;
            }
            return delegate.addFont(path, weight, italic);
        }
        return false;
    }

    @LayoutlibDelegate
    /*package*/ static boolean nAddFontFromAssetManager(long builderPtr, AssetManager mgr, String path,
            int cookie, boolean isAsset, int ttcIndex, int weight, int isItalic) {
        FontFamily_Delegate ffd = sManager.getDelegate(builderPtr);
        if (ffd == null) {
            return false;
        }
        ffd.mValid = true;
        if (mgr == null) {
            return false;
        }
        if (mgr instanceof BridgeAssetManager) {
            InputStream fontStream = null;
            try {
                AssetRepository assetRepository = ((BridgeAssetManager) mgr).getAssetRepository();
                if (assetRepository == null) {
                    Bridge.getLog().error(LayoutLog.TAG_MISSING_ASSET, "Asset not found: " + path,
                            null);
                    return false;
                }
                if (!assetRepository.isSupported()) {
                    // Don't log any warnings on unsupported IDEs.
                    return false;
                }
                // Check cache
                FontInfo fontInfo = sCache.get(path);
                if (fontInfo != null) {
                    // renew the font's lease.
                    sCache.put(path, fontInfo);
                    ffd.addFont(fontInfo);
                    return true;
                }
                fontStream = isAsset ?
                        assetRepository.openAsset(path, AssetManager.ACCESS_STREAMING) :
                        assetRepository.openNonAsset(cookie, path, AssetManager.ACCESS_STREAMING);
                if (fontStream == null) {
                    Bridge.getLog().error(LayoutLog.TAG_MISSING_ASSET, "Asset not found: " + path,
                            path);
                    return false;
                }
                Font font = Font.createFont(Font.TRUETYPE_FONT, fontStream);
                fontInfo = new FontInfo();
                fontInfo.mFont = font;
                if (weight == RESOLVE_BY_FONT_TABLE) {
                    fontInfo.mWeight = FontUtilities.getFont2D(font).getWeight();
                } else {
                    fontInfo.mWeight = weight;
                }
                if (isItalic == RESOLVE_BY_FONT_TABLE) {
                    fontInfo.mIsItalic =
                            (FontUtilities.getFont2D(font).getStyle() & Font.ITALIC) != 0;
                } else {
                    fontInfo.mIsItalic = isItalic == 1;
                }
                ffd.addFont(fontInfo);
                return true;
            } catch (IOException e) {
                Bridge.getLog().error(LayoutLog.TAG_MISSING_ASSET, "Unable to load font " + path, e,
                        path);
            } catch (FontFormatException e) {
                if (path.endsWith(EXTENSION_OTF)) {
                    // otf fonts are not supported on the user's config (JRE version + OS)
                    Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
                            "OpenType fonts are not supported yet: " + path, null, path);
                } else {
                    Bridge.getLog().error(LayoutLog.TAG_BROKEN,
                            "Unable to load font " + path, e, path);
                }
            } finally {
                if (fontStream != null) {
                    try {
                        fontStream.close();
                    } catch (IOException ignored) {
                    }
                }
            }
            return false;
        }
        // This should never happen. AssetManager is a final class (from user's perspective), and
        // we've replaced every creation of AssetManager with our implementation. We create an
        // exception and log it, but continue with rest of the rendering, without loading this font.
        Bridge.getLog().error(LayoutLog.TAG_BROKEN,
                "You have found a bug in the rendering library. Please file a bug at b.android.com.",
                new RuntimeException("Asset Manager is not an instance of BridgeAssetManager"),
                null);
        return false;
    }

    @LayoutlibDelegate
    /*package*/ static long nGetBuilderReleaseFunc() {
        // Layoutlib uses the same reference for the builder and the font family,
        // so it should not release that reference at the builder stage.
        return -1;
    }

    // ---- private helper methods ----

    private void init() {
        for (Runnable postInitRunnable : mPostInitRunnables) {
            postInitRunnable.run();
        }
        mPostInitRunnables = null;
    }

    private boolean addFont(final String path, int ttcIndex, int weight, int italic) {
        // FIXME: support ttc fonts. Hack JRE??
        if (sFontLocation == null) {
            mPostInitRunnables.add(() -> addFont(path, weight, italic));
            return true;
        }
        return addFont(path, weight, italic);
    }

     private boolean addFont(@NonNull String path) {
         return addFont(path, DEFAULT_FONT_WEIGHT, path.endsWith(FONT_SUFFIX_ITALIC) ? 1 : RESOLVE_BY_FONT_TABLE);
     }

    private boolean addFont(@NonNull String path, int weight, int italic) {
        if (path.startsWith(SYSTEM_FONTS) &&
                !SDK_FONTS.contains(path.substring(SYSTEM_FONTS.length()))) {
            Logger.getLogger(FontFamily_Delegate.class.getSimpleName()).warning("Unable to load font " + path);
            return mValid = false;
        }
        // Set valid to true, even if the font fails to load.
        mValid = true;
        Font font = loadFont(path);
        if (font == null) {
            return false;
        }
        FontInfo fontInfo = new FontInfo();
        fontInfo.mFont = font;
        fontInfo.mWeight = weight;
        fontInfo.mIsItalic = italic == RESOLVE_BY_FONT_TABLE ? font.isItalic() : italic == 1;
        addFont(fontInfo);
        return true;
    }

    private boolean addFont(@NonNull FontInfo fontInfo) {
        return mFonts.putIfAbsent(fontInfo, fontInfo.mFont) == null;
    }

    /**
     * Compute matching metric between two styles - 0 is an exact match.
     */
    public static int computeMatch(@NonNull FontInfo font1, @NonNull FontInfo font2) {
        int score = Math.abs(font1.mWeight / 100 - font2.mWeight / 100);
        if (font1.mIsItalic != font2.mIsItalic) {
            score += 2;
        }
        return score;
    }

    /**
     * Try to derive a font from {@code srcFont} for the style in {@code outFont}.
     * <p/>
     * {@code outFont} is updated to reflect the style of the derived font.
     * @param srcFont the source font
     * @param outFont contains the desired font style. Updated to contain the derived font and
     *                its style
     */
    public static void deriveFont(@NonNull FontInfo srcFont, @NonNull FontInfo outFont) {
        int desiredWeight = outFont.mWeight;
        int srcWeight = srcFont.mWeight;
        assert srcFont.mFont != null;
        Font derivedFont = srcFont.mFont;
        int derivedStyle = 0;
        // Embolden the font if required.
        if (desiredWeight >= BOLD_FONT_WEIGHT && desiredWeight - srcWeight > BOLD_FONT_WEIGHT_DELTA / 2) {
            derivedStyle |= Font.BOLD;
            srcWeight += BOLD_FONT_WEIGHT_DELTA;
        }
        // Italicize the font if required.
        if (outFont.mIsItalic && !srcFont.mIsItalic) {
            derivedStyle |= Font.ITALIC;
        } else if (outFont.mIsItalic != srcFont.mIsItalic) {
            // The desired font is plain, but the src font is italics. We can't convert it back. So
            // we update the value to reflect the true style of the font we're deriving.
            outFont.mIsItalic = srcFont.mIsItalic;
        }

        if (derivedStyle != 0) {
            derivedFont = derivedFont.deriveFont(derivedStyle);
        }

        outFont.mFont = derivedFont;
        outFont.mWeight = srcWeight;
        // No need to update mIsItalics, as it's already been handled above.
    }
}
