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

import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.res.AssetManager;
import android.content.res.Resources;
import android.os.LocaleList;
import android.os.ParcelFileDescriptor;
import android.util.TypedValue;

import com.android.internal.util.Preconditions;

import dalvik.annotation.optimization.CriticalNative;

import libcore.util.NativeAllocationRegistry;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.util.Arrays;
import java.util.Objects;

/**
 * A font class can be used for creating FontFamily.
 */
public final class Font {
    private static final String TAG = "Font";

    private static final int NOT_SPECIFIED = -1;
    private static final int STYLE_ITALIC = 1;
    private static final int STYLE_NORMAL = 0;

    /**
     * A builder class for creating new Font.
     */
    public static final class Builder {
        private static final NativeAllocationRegistry sAssetByteBufferRegistry =
                NativeAllocationRegistry.createMalloced(ByteBuffer.class.getClassLoader(),
                    nGetReleaseNativeAssetFunc());

        private static final NativeAllocationRegistry sFontRegistry =
                NativeAllocationRegistry.createMalloced(Font.class.getClassLoader(),
                    nGetReleaseNativeFont());

        private @Nullable ByteBuffer mBuffer;
        private @Nullable File mFile;
        private @NonNull String mLocaleList = "";
        private @IntRange(from = -1, to = 1000) int mWeight = NOT_SPECIFIED;
        private @IntRange(from = -1, to = 1) int mItalic = NOT_SPECIFIED;
        private @IntRange(from = 0) int mTtcIndex = 0;
        private @Nullable FontVariationAxis[] mAxes = null;
        private @Nullable IOException mException;

        /**
         * Constructs a builder with a byte buffer.
         *
         * Note that only direct buffer can be used as the source of font data.
         *
         * @see ByteBuffer#allocateDirect(int)
         * @param buffer a byte buffer of a font data
         */
        public Builder(@NonNull ByteBuffer buffer) {
            Preconditions.checkNotNull(buffer, "buffer can not be null");
            if (!buffer.isDirect()) {
                throw new IllegalArgumentException(
                        "Only direct buffer can be used as the source of font data.");
            }
            mBuffer = buffer;
        }

        /**
         * Construct a builder with a byte buffer and file path.
         *
         * This method is intended to be called only from SystemFonts.
         * @hide
         */
        public Builder(@NonNull ByteBuffer buffer, @NonNull File path,
                @NonNull String localeList) {
            this(buffer);
            mFile = path;
            mLocaleList = localeList;
        }

        /**
         * Constructs a builder with a file path.
         *
         * @param path a file path to the font file
         */
        public Builder(@NonNull File path) {
            Preconditions.checkNotNull(path, "path can not be null");
            try (FileInputStream fis = new FileInputStream(path)) {
                final FileChannel fc = fis.getChannel();
                mBuffer = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size());
            } catch (IOException e) {
                mException = e;
            }
            mFile = path;
        }

        /**
         * Constructs a builder with a file descriptor.
         *
         * @param fd a file descriptor
         */
        public Builder(@NonNull ParcelFileDescriptor fd) {
            this(fd, 0, -1);
        }

        /**
         * Constructs a builder with a file descriptor.
         *
         * @param fd a file descriptor
         * @param offset an offset to of the font data in the file
         * @param size a size of the font data. If -1 is passed, use until end of the file.
         */
        public Builder(@NonNull ParcelFileDescriptor fd, @IntRange(from = 0) long offset,
                @IntRange(from = -1) long size) {
            try (FileInputStream fis = new FileInputStream(fd.getFileDescriptor())) {
                final FileChannel fc = fis.getChannel();
                size = (size == -1) ? fc.size() - offset : size;
                mBuffer = fc.map(FileChannel.MapMode.READ_ONLY, offset, size);
            } catch (IOException e) {
                mException = e;
            }
        }

        /**
         * Constructs a builder from an asset manager and a file path in an asset directory.
         *
         * @param am the application's asset manager
         * @param path the file name of the font data in the asset directory
         */
        public Builder(@NonNull AssetManager am, @NonNull String path) {
            this(am, path, true /* is asset */, 0 /* cookie */);
        }

        /**
         * Constructs a builder from an asset manager and a file path in an asset directory.
         *
         * @param am the application's asset manager
         * @param path the file name of the font data in the asset directory
         * @param isAsset true if the undelying data is in asset
         * @param cookie set asset cookie
         * @hide
         */
        public Builder(@NonNull AssetManager am, @NonNull String path, boolean isAsset,
                int cookie) {
            final long nativeAsset = nGetNativeAsset(am, path, isAsset, cookie);
            if (nativeAsset == 0) {
                mException = new FileNotFoundException("Unable to open " + path);
                return;
            }
            final ByteBuffer b = nGetAssetBuffer(nativeAsset);
            sAssetByteBufferRegistry.registerNativeAllocation(b, nativeAsset);
            if (b == null) {
                mException = new FileNotFoundException(path + " not found");
                return;
            }
            mBuffer = b;
        }

        /**
         * Constructs a builder from resources.
         *
         * Resource ID must points the font file. XML font can not be used here.
         *
         * @param res the resource of this application.
         * @param resId the resource ID of font file.
         */
        public Builder(@NonNull Resources res, int resId) {
            final TypedValue value = new TypedValue();
            res.getValue(resId, value, true);
            if (value.string == null) {
                mException = new FileNotFoundException(resId + " not found");
                return;
            }
            final String str = value.string.toString();
            if (str.toLowerCase().endsWith(".xml")) {
                mException = new FileNotFoundException(resId + " must be font file.");
                return;
            }
            final long nativeAsset = nGetNativeAsset(res.getAssets(), str, false /* is asset */,
                    value.assetCookie);
            if (nativeAsset == 0) {
                mException = new FileNotFoundException("Unable to open " + str);
                return;
            }
            final ByteBuffer b = nGetAssetBuffer(nativeAsset);
            sAssetByteBufferRegistry.registerNativeAllocation(b, nativeAsset);
            if (b == null) {
                mException = new FileNotFoundException(str + " not found");
                return;
            }
            mBuffer = b;
        }

        /**
         * Sets weight of the font.
         *
         * Tells the system the weight of the given font. If this function is not called, the system
         * will resolve the weight value by reading font tables.
         *
         * Here are pairs of the common names and their values.
         * <p>
         *  <table>
         *  <thead>
         *  <tr>
         *  <th align="center">Value</th>
         *  <th align="center">Name</th>
         *  <th align="center">Android Definition</th>
         *  </tr>
         *  </thead>
         *  <tbody>
         *  <tr>
         *  <td align="center">100</td>
         *  <td align="center">Thin</td>
         *  <td align="center">{@link FontStyle#FONT_WEIGHT_THIN}</td>
         *  </tr>
         *  <tr>
         *  <td align="center">200</td>
         *  <td align="center">Extra Light (Ultra Light)</td>
         *  <td align="center">{@link FontStyle#FONT_WEIGHT_EXTRA_LIGHT}</td>
         *  </tr>
         *  <tr>
         *  <td align="center">300</td>
         *  <td align="center">Light</td>
         *  <td align="center">{@link FontStyle#FONT_WEIGHT_LIGHT}</td>
         *  </tr>
         *  <tr>
         *  <td align="center">400</td>
         *  <td align="center">Normal (Regular)</td>
         *  <td align="center">{@link FontStyle#FONT_WEIGHT_NORMAL}</td>
         *  </tr>
         *  <tr>
         *  <td align="center">500</td>
         *  <td align="center">Medium</td>
         *  <td align="center">{@link FontStyle#FONT_WEIGHT_MEDIUM}</td>
         *  </tr>
         *  <tr>
         *  <td align="center">600</td>
         *  <td align="center">Semi Bold (Demi Bold)</td>
         *  <td align="center">{@link FontStyle#FONT_WEIGHT_SEMI_BOLD}</td>
         *  </tr>
         *  <tr>
         *  <td align="center">700</td>
         *  <td align="center">Bold</td>
         *  <td align="center">{@link FontStyle#FONT_WEIGHT_BOLD}</td>
         *  </tr>
         *  <tr>
         *  <td align="center">800</td>
         *  <td align="center">Extra Bold (Ultra Bold)</td>
         *  <td align="center">{@link FontStyle#FONT_WEIGHT_EXTRA_BOLD}</td>
         *  </tr>
         *  <tr>
         *  <td align="center">900</td>
         *  <td align="center">Black (Heavy)</td>
         *  <td align="center">{@link FontStyle#FONT_WEIGHT_BLACK}</td>
         *  </tr>
         *  </tbody>
         * </p>
         *
         * @see FontStyle#FONT_WEIGHT_THIN
         * @see FontStyle#FONT_WEIGHT_EXTRA_LIGHT
         * @see FontStyle#FONT_WEIGHT_LIGHT
         * @see FontStyle#FONT_WEIGHT_NORMAL
         * @see FontStyle#FONT_WEIGHT_MEDIUM
         * @see FontStyle#FONT_WEIGHT_SEMI_BOLD
         * @see FontStyle#FONT_WEIGHT_BOLD
         * @see FontStyle#FONT_WEIGHT_EXTRA_BOLD
         * @see FontStyle#FONT_WEIGHT_BLACK
         * @param weight a weight value
         * @return this builder
         */
        public @NonNull Builder setWeight(
                @IntRange(from = FontStyle.FONT_WEIGHT_MIN, to = FontStyle.FONT_WEIGHT_MAX)
                int weight) {
            Preconditions.checkArgument(
                    FontStyle.FONT_WEIGHT_MIN <= weight && weight <= FontStyle.FONT_WEIGHT_MAX);
            mWeight = weight;
            return this;
        }

        /**
         * Sets italic information of the font.
         *
         * Tells the system the style of the given font. If this function is not called, the system
         * will resolve the style by reading font tables.
         *
         * For example, if you want to use italic font as upright font, call {@code
         * setSlant(FontStyle.FONT_SLANT_UPRIGHT)} explicitly.
         *
         * @return this builder
         */
        public @NonNull Builder setSlant(@FontStyle.FontSlant int slant) {
            mItalic = slant == FontStyle.FONT_SLANT_UPRIGHT ? STYLE_NORMAL : STYLE_ITALIC;
            return this;
        }

        /**
         * Sets an index of the font collection. See {@link android.R.attr#ttcIndex}.
         *
         * @param ttcIndex An index of the font collection. If the font source is not font
         *                 collection, do not call this method or specify 0.
         * @return this builder
         */
        public @NonNull Builder setTtcIndex(@IntRange(from = 0) int ttcIndex) {
            mTtcIndex = ttcIndex;
            return this;
        }

        /**
         * Sets the font variation settings.
         *
         * @param variationSettings see {@link FontVariationAxis#fromFontVariationSettings(String)}
         * @return this builder
         * @throws IllegalArgumentException If given string is not a valid font variation settings
         *                                  format.
         */
        public @NonNull Builder setFontVariationSettings(@Nullable String variationSettings) {
            mAxes = FontVariationAxis.fromFontVariationSettings(variationSettings);
            return this;
        }

        /**
         * Sets the font variation settings.
         *
         * @param axes an array of font variation axis tag-value pairs
         * @return this builder
         */
        public @NonNull Builder setFontVariationSettings(@Nullable FontVariationAxis[] axes) {
            mAxes = axes == null ? null : axes.clone();
            return this;
        }

        /**
         * Creates the font based on the configured values.
         * @return the Font object
         */
        public @NonNull Font build() throws IOException {
            if (mException != null) {
                throw new IOException("Failed to read font contents", mException);
            }
            if (mWeight == NOT_SPECIFIED || mItalic == NOT_SPECIFIED) {
                final int packed = FontFileUtil.analyzeStyle(mBuffer, mTtcIndex, mAxes);
                if (FontFileUtil.isSuccess(packed)) {
                    if (mWeight == NOT_SPECIFIED) {
                        mWeight = FontFileUtil.unpackWeight(packed);
                    }
                    if (mItalic == NOT_SPECIFIED) {
                        mItalic = FontFileUtil.unpackItalic(packed) ? STYLE_ITALIC : STYLE_NORMAL;
                    }
                } else {
                    mWeight = 400;
                    mItalic = STYLE_NORMAL;
                }
            }
            mWeight = Math.max(FontStyle.FONT_WEIGHT_MIN,
                    Math.min(FontStyle.FONT_WEIGHT_MAX, mWeight));
            final boolean italic = (mItalic == STYLE_ITALIC);
            final int slant = (mItalic == STYLE_ITALIC)
                    ? FontStyle.FONT_SLANT_ITALIC : FontStyle.FONT_SLANT_UPRIGHT;
            final long builderPtr = nInitBuilder();
            if (mAxes != null) {
                for (FontVariationAxis axis : mAxes) {
                    nAddAxis(builderPtr, axis.getOpenTypeTagValue(), axis.getStyleValue());
                }
            }
            final ByteBuffer readonlyBuffer = mBuffer.asReadOnlyBuffer();
            final String filePath = mFile == null ? "" : mFile.getAbsolutePath();
            final long ptr = nBuild(builderPtr, readonlyBuffer, filePath, mWeight, italic,
                    mTtcIndex);
            final Font font = new Font(ptr, readonlyBuffer, mFile,
                    new FontStyle(mWeight, slant), mTtcIndex, mAxes, mLocaleList);
            sFontRegistry.registerNativeAllocation(font, ptr);
            return font;
        }

        /**
         * Native methods for accessing underlying buffer in Asset
         */
        private static native long nGetNativeAsset(
                @NonNull AssetManager am, @NonNull String path, boolean isAsset, int cookie);
        private static native ByteBuffer nGetAssetBuffer(long nativeAsset);
        @CriticalNative
        private static native long nGetReleaseNativeAssetFunc();

        /**
         * Native methods for creating Font
         */
        private static native long nInitBuilder();
        @CriticalNative
        private static native void nAddAxis(long builderPtr, int tag, float value);
        private static native long nBuild(
                long builderPtr, @NonNull ByteBuffer buffer, @NonNull String filePath, int weight,
                boolean italic, int ttcIndex);
        @CriticalNative
        private static native long nGetReleaseNativeFont();
    }

    private final long mNativePtr;  // address of the shared ptr of minikin::Font
    private final @NonNull ByteBuffer mBuffer;
    private final @Nullable File mFile;
    private final FontStyle mFontStyle;
    private final @IntRange(from = 0) int mTtcIndex;
    private final @Nullable FontVariationAxis[] mAxes;
    private final @NonNull String mLocaleList;

    /**
     * Use Builder instead
     */
    private Font(long nativePtr, @NonNull ByteBuffer buffer, @Nullable File file,
            @NonNull FontStyle fontStyle, @IntRange(from = 0) int ttcIndex,
            @Nullable FontVariationAxis[] axes, @NonNull String localeList) {
        mBuffer = buffer;
        mFile = file;
        mFontStyle = fontStyle;
        mNativePtr = nativePtr;
        mTtcIndex = ttcIndex;
        mAxes = axes;
        mLocaleList = localeList;
    }

    /**
     * Returns a font file buffer.
     *
     * @return a font buffer
     */
    public @NonNull ByteBuffer getBuffer() {
        return mBuffer;
    }

    /**
     * Returns a file path of this font.
     *
     * This returns null if this font is not created from regular file.
     *
     * @return a file path of the font
     */
    public @Nullable File getFile() {
        return mFile;
    }

    /**
     * Get a style associated with this font.
     *
     * @see Builder#setWeight(int)
     * @see Builder#setSlant(int)
     * @return a font style
     */
    public @NonNull FontStyle getStyle() {
        return mFontStyle;
    }

    /**
     * Get a TTC index value associated with this font.
     *
     * If TTF/OTF file is provided, this value is always 0.
     *
     * @see Builder#setTtcIndex(int)
     * @return a TTC index value
     */
    public @IntRange(from = 0) int getTtcIndex() {
        return mTtcIndex;
    }

    /**
     * Get a font variation settings associated with this font
     *
     * @see Builder#setFontVariationSettings(String)
     * @see Builder#setFontVariationSettings(FontVariationAxis[])
     * @return font variation settings
     */
    public @Nullable FontVariationAxis[] getAxes() {
        return mAxes == null ? null : mAxes.clone();
    }

    /**
     * Get a locale list of this font.
     *
     * This is always empty if this font is not a system font.
     * @return a locale list
     */
    public @NonNull LocaleList getLocaleList() {
        return LocaleList.forLanguageTags(mLocaleList);
    }

    /** @hide */
    public long getNativePtr() {
        return mNativePtr;
    }

    @Override
    public boolean equals(@Nullable Object o) {
        if (o == this) {
            return true;
        }
        if (o == null || !(o instanceof Font)) {
            return false;
        }
        Font f = (Font) o;
        return mFontStyle.equals(f.mFontStyle) && f.mTtcIndex == mTtcIndex
                && Arrays.equals(f.mAxes, mAxes) && f.mBuffer.equals(mBuffer);
    }

    @Override
    public int hashCode() {
        return Objects.hash(mFontStyle, mTtcIndex, Arrays.hashCode(mAxes), mBuffer);
    }

    @Override
    public String toString() {
        return "Font {"
            + "path=" + mFile
            + ", style=" + mFontStyle
            + ", ttcIndex=" + mTtcIndex
            + ", axes=" + FontVariationAxis.toFontVariationSettings(mAxes)
            + ", localeList=" + mLocaleList
            + ", buffer=" + mBuffer
            + "}";
    }
}
