/*
 * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package sun.font;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Locale;
import java.util.Properties;
import java.util.Scanner;

import sun.awt.FcFontManager;
import sun.awt.FontConfiguration;
import sun.awt.FontDescriptor;
import sun.awt.SunToolkit;
import sun.font.FontConfigManager.FcCompFont;
import sun.font.FontConfigManager.FontConfigFont;
import sun.font.FontConfigManager.FontConfigInfo;
import sun.util.logging.PlatformLogger;

import static java.nio.charset.StandardCharsets.ISO_8859_1;

public final class FcFontConfiguration extends FontConfiguration {

    /** Version of the cache file format understood by this code.
     * Its part of the file name so that we can rev this at
     * any time, even in a minor JDK update.
     * It is stored as the value of the "version" property.
     * This is distinct from the version of "libfontconfig" that generated
     * the cached results, and which is the "fcversion" property in the file.
     * {@code FontConfiguration.getVersion()} also returns a version string,
     * and has meant the version of the fontconfiguration.properties file
     * that was read. Since this class doesn't use such files, then what
     * that really means is whether the methods on this class return
     * values that are compatible with the classes that do directly read
     * from such files. It is a compatible subset of version "1".
     */
    private static final String fileVersion = "1";
    private String fcInfoFileName = null;

    private FcCompFont[] fcCompFonts = null;

    public FcFontConfiguration(SunFontManager fm) {
        super(fm);
        init();
    }

    /* This isn't called but is needed to satisfy super-class contract. */
    public FcFontConfiguration(SunFontManager fm,
                               boolean preferLocaleFonts,
                               boolean preferPropFonts) {
        super(fm, preferLocaleFonts, preferPropFonts);
        init();
    }

    @Override
    public synchronized boolean init() {
        if (fcCompFonts != null) {
            return true;
        }

        setFontConfiguration();
        readFcInfo();
        FcFontManager fm = (FcFontManager) fontManager;
        FontConfigManager fcm = fm.getFontConfigManager();
        if (fcCompFonts == null) {
            fcCompFonts = fcm.loadFontConfig();
            if (fcCompFonts != null) {
                try {
                    writeFcInfo();
                } catch (Exception e) {
                    if (FontUtilities.debugFonts()) {
                        warning("Exception writing fcInfo " + e);
                    }
                }
            } else if (FontUtilities.debugFonts()) {
                warning("Failed to get info from libfontconfig");
            }
        } else {
            fcm.populateFontConfig(fcCompFonts);
        }

        if (fcCompFonts == null) {
            return false; // couldn't load fontconfig.
        }

        // NB already in a privileged block from SGE
        String javaHome = System.getProperty("java.home");
        if (javaHome == null) {
            throw new Error("java.home property not set");
        }
        String javaLib = javaHome + File.separator + "lib";
        getInstalledFallbackFonts(javaLib);

        return true;
    }

    @Override
    public String getFallbackFamilyName(String fontName,
                                        String defaultFallback) {
        // maintain compatibility with old font.properties files, which either
        // had aliases for TimesRoman & Co. or defined mappings for them.
        String compatibilityName = getCompatibilityFamilyName(fontName);
        if (compatibilityName != null) {
            return compatibilityName;
        }
        return defaultFallback;
    }

    @Override
    protected String
        getFaceNameFromComponentFontName(String componentFontName) {
        return null;
    }

    @Override
    protected String
        getFileNameFromComponentFontName(String componentFontName) {
        return null;
    }

    @Override
    public String getFileNameFromPlatformName(String platformName) {
        /* Platform name is the file name, but rather than returning
         * the arg, return null*/
        return null;
    }

    @Override
    protected Charset getDefaultFontCharset(String fontName) {
        return ISO_8859_1;
    }

    @Override
    protected String getEncoding(String awtFontName,
                                 String characterSubsetName) {
        return "default";
    }

    @Override
    protected void initReorderMap() {
        reorderMap = new HashMap<>();
    }

    @Override
    protected FontDescriptor[] buildFontDescriptors(int fontIndex, int styleIndex) {
        CompositeFontDescriptor[] cfi = get2DCompositeFontInfo();
        int idx = fontIndex * NUM_STYLES + styleIndex;
        String[] componentFaceNames = cfi[idx].getComponentFaceNames();
        FontDescriptor[] ret = new FontDescriptor[componentFaceNames.length];
        for (int i = 0; i < componentFaceNames.length; i++) {
            ret[i] = new FontDescriptor(componentFaceNames[i], ISO_8859_1.newEncoder(), new int[0]);
        }

        return ret;
    }

    @Override
    public int getNumberCoreFonts() {
        return 1;
    }

    @Override
    public String[] getPlatformFontNames() {
        HashSet<String> nameSet = new HashSet<String>();
        FcFontManager fm = (FcFontManager) fontManager;
        FontConfigManager fcm = fm.getFontConfigManager();
        FcCompFont[] fcCompFonts = fcm.loadFontConfig();
        for (int i=0; i<fcCompFonts.length; i++) {
            for (int j=0; j<fcCompFonts[i].allFonts.length; j++) {
                nameSet.add(fcCompFonts[i].allFonts[j].fontFile);
            }
        }
        return nameSet.toArray(new String[0]);
    }

    @Override
    public String getExtraFontPath() {
        return null;
    }

    @Override
    public boolean needToSearchForFile(String fileName) {
        return false;
    }

    private FontConfigFont[] getFcFontList(FcCompFont[] fcFonts,
                                           String fontname, int style) {

        if (fontname.equals("dialog")) {
            fontname = "sansserif";
        } else if (fontname.equals("dialoginput")) {
            fontname = "monospaced";
        }
        for (int i=0; i<fcFonts.length; i++) {
            if (fontname.equals(fcFonts[i].jdkName) &&
                style == fcFonts[i].style) {
                return fcFonts[i].allFonts;
            }
        }
        return fcFonts[0].allFonts;
    }

    @Override
    public CompositeFontDescriptor[] get2DCompositeFontInfo() {

        FcFontManager fm = (FcFontManager) fontManager;
        FontConfigManager fcm = fm.getFontConfigManager();
        FcCompFont[] fcCompFonts = fcm.loadFontConfig();

        CompositeFontDescriptor[] result =
                new CompositeFontDescriptor[NUM_FONTS * NUM_STYLES];

        for (int fontIndex = 0; fontIndex < NUM_FONTS; fontIndex++) {
            String fontName = publicFontNames[fontIndex];

            for (int styleIndex = 0; styleIndex < NUM_STYLES; styleIndex++) {

                String faceName = fontName + "." + styleNames[styleIndex];
                FontConfigFont[] fcFonts =
                    getFcFontList(fcCompFonts,
                                  fontNames[fontIndex], styleIndex);

                int numFonts = fcFonts.length;
                // fall back fonts listed in the lib/fonts/fallback directory
                if (installedFallbackFontFiles != null) {
                    numFonts += installedFallbackFontFiles.length;
                }

                String[] fileNames = new String[numFonts];
                String[] faceNames = new String[numFonts];

                int index;
                for (index = 0; index < fcFonts.length; index++) {
                    fileNames[index] = fcFonts[index].fontFile;
                    faceNames[index] = fcFonts[index].fullName;
                }

                if (installedFallbackFontFiles != null) {
                    System.arraycopy(installedFallbackFontFiles, 0,
                                     fileNames, fcFonts.length,
                                     installedFallbackFontFiles.length);
                }

                result[fontIndex * NUM_STYLES + styleIndex]
                        = new CompositeFontDescriptor(
                            faceName,
                            1,
                            faceNames,
                            fileNames,
                            null, null);
            }
        }
        return result;
    }

    /**
     * Gets the OS version string from a Linux release-specific file.
     */
    private String getVersionString(File f) {
        try (Scanner sc  = new Scanner(f)) {
            return sc.findInLine("(\\d)+((\\.)(\\d)+)*");
        } catch (Exception e) {
        }
        return null;
    }

    private String extractInfo(String s) {
        if (s == null) {
            return null;
        }
        if (s.startsWith("\"")) s = s.substring(1);
        if (s.endsWith("\"")) s = s.substring(0, s.length()-1);
        s = s.replace(' ', '_');
        return s;
    }

    /**
     * Sets the OS name and version from environment information.
     */
    @Override
    protected void setOsNameAndVersion() {

        super.setOsNameAndVersion();

        if (!osName.equals("Linux")) {
            return;
        }
        try {
            File f;
            if ((f = new File("/etc/lsb-release")).canRead()) {
                    /* Ubuntu and (perhaps others) use only lsb-release.
                     * Syntax and encoding is compatible with java properties.
                     * For Ubuntu the ID is "Ubuntu".
                     */
                    Properties props = new Properties();
                    try (FileInputStream fis = new FileInputStream(f)) {
                        props.load(fis);
                    }
                    osName = extractInfo(props.getProperty("DISTRIB_ID"));
                    osVersion = extractInfo(props.getProperty("DISTRIB_RELEASE"));
            } else if ((f = new File("/etc/redhat-release")).canRead()) {
                osName = "RedHat";
                osVersion = getVersionString(f);
            } else if ((f = new File("/etc/SuSE-release")).canRead()) {
                osName = "SuSE";
                osVersion = getVersionString(f);
            } else if ((f = new File("/etc/turbolinux-release")).canRead()) {
                osName = "Turbo";
                osVersion = getVersionString(f);
            } else if ((f = new File("/etc/fedora-release")).canRead()) {
                osName = "Fedora";
                osVersion = getVersionString(f);
            } else if ((f = new File("/etc/os-release")).canRead()) {
                Properties props = new Properties();
                try (FileInputStream fis = new FileInputStream(f)) {
                    props.load(fis);
                }
                osName = extractInfo(props.getProperty("NAME"));
                osVersion = extractInfo(props.getProperty("VERSION_ID"));
                if (osName.equals("SLES")) {
                    osName = "SuSE";
                } else {
                    osName = extractInfo(props.getProperty("ID"));
                }
            }
        } catch (Exception e) {
            if (FontUtilities.debugFonts()) {
                warning("Exception identifying Linux distro.");
            }
        }
    }

    private File getFcInfoFile() {
        if (fcInfoFileName == null) {
            String hostname;
            try {
                hostname = InetAddress.getLocalHost().getHostName();
            } catch (UnknownHostException e) {
                hostname = "localhost";
            }
            String userDir = System.getProperty("user.home");
            String version = System.getProperty("java.version");
            String fs = File.separator;
            String dir = userDir+fs+".java"+fs+"fonts"+fs+version;
            Locale locale = SunToolkit.getStartupLocale();
            String lang = locale.getLanguage();
            String country = locale.getCountry();
            String name = "fcinfo-"+fileVersion+"-"+hostname+"-"+
                osName+"-"+osVersion+"-"+lang+"-"+country+".properties";
            fcInfoFileName = dir+fs+name;
        }
        return new File(fcInfoFileName);
    }

    private void writeFcInfo() {
        Properties props = new Properties();
        props.setProperty("version", fileVersion);
        FcFontManager fm = (FcFontManager) fontManager;
        FontConfigManager fcm = fm.getFontConfigManager();
        FontConfigInfo fcInfo = fcm.getFontConfigInfo();
        props.setProperty("fcversion", Integer.toString(fcInfo.fcVersion));
        if (fcInfo.cacheDirs != null) {
            for (int i=0;i<fcInfo.cacheDirs.length;i++) {
                if (fcInfo.cacheDirs[i] != null) {
                   props.setProperty("cachedir."+i,  fcInfo.cacheDirs[i]);
                }
            }
        }
        for (int i=0; i<fcCompFonts.length; i++) {
            FcCompFont fci = fcCompFonts[i];
            String styleKey = fci.jdkName+"."+fci.style;
            props.setProperty(styleKey+".length",
                              Integer.toString(fci.allFonts.length));
            for (int j=0; j<fci.allFonts.length; j++) {
                props.setProperty(styleKey+"."+j+".file",
                                  fci.allFonts[j].fontFile);
                if (fci.allFonts[j].fullName != null) {
                    props.setProperty(styleKey+"."+j+".fullName",
                                      fci.allFonts[j].fullName);
                }
            }
        }
        try {
            /* This writes into a temp file then renames when done.
             * Since the rename is an atomic action within the same
             * directory no client will ever see a partially written file.
             */
            File fcInfoFile = getFcInfoFile();
            File dir = fcInfoFile.getParentFile();
            dir.mkdirs();
            File tempFile = Files.createTempFile(dir.toPath(), "fcinfo", null).toFile();
            try (FileOutputStream fos = new FileOutputStream(tempFile)) {
                props.store(fos, "JDK Font Configuration Generated File: *Do Not Edit*");
            }
            boolean renamed = tempFile.renameTo(fcInfoFile);
            if (!renamed && FontUtilities.debugFonts()) {
                System.out.println("rename failed");
                warning("Failed renaming file to "+ getFcInfoFile());
            }
        } catch (Exception e) {
            if (FontUtilities.debugFonts()) {
                warning("IOException writing to "+ getFcInfoFile());
            }
        }
    }

    /* We want to be able to use this cache instead of invoking
     * fontconfig except when we can detect the system cache has changed.
     * But there doesn't seem to be a way to find the location of
     * the system cache.
     */
    private void readFcInfo() {
        File fcFile = getFcInfoFile();
        if (!fcFile.exists()) {
            if (FontUtilities.debugFonts()) {
                warning("fontconfig info file " + fcFile.toString() + " does not exist");
            }
            return;
        }
        Properties props = new Properties();
        try (FileInputStream fis = new FileInputStream(fcFile)) {
            props.load(fis);
        } catch (IOException e) {
            if (FontUtilities.debugFonts()) {
                warning("IOException (" + e.getCause() + ") reading from " + fcFile.toString());
            }
            return;
        }
        String version = (String)props.get("version");
        if (version == null || !version.equals(fileVersion)) {
            if (FontUtilities.debugFonts()) {
                warning("fontconfig info file version mismatch (found: " + version +
                    ", expected: " + fileVersion + ")");
            }
            return;
        }

        // If there's a new, different fontconfig installed on the
        // system, we invalidate our fontconfig file.
        String fcVersionStr = (String)props.get("fcversion");
        if (fcVersionStr != null) {
            int fcVersion;
            try {
                fcVersion = Integer.parseInt(fcVersionStr);
                if (fcVersion != 0 &&
                    fcVersion != FontConfigManager.getFontConfigVersion()) {
                    if (FontUtilities.debugFonts()) {
                        warning("new, different fontconfig detected");
                    }
                    return;
                }
            } catch (Exception e) {
                if (FontUtilities.debugFonts()) {
                    warning("Exception parsing version " + fcVersionStr);
                }
                return;
            }
        }

        // If we can locate the fontconfig cache dirs, then compare the
        // time stamp of those with our properties file. If we are out
        // of date then re-generate.
        long lastModified = fcFile.lastModified();
        int cacheDirIndex = 0;
        while (cacheDirIndex<4) { // should never be more than 2 anyway.
            String dir = (String)props.get("cachedir."+cacheDirIndex);
            if (dir == null) {
                break;
            }
            File dirFile = new File(dir);
            if (dirFile.exists() && dirFile.lastModified() > lastModified) {
                if (FontUtilities.debugFonts()) {
                    warning("out of date cache directories detected");
                }
                return;
            }
            cacheDirIndex++;
        }

        String[] names = { "sansserif", "serif", "monospaced" };
        String[] fcnames = { "sans", "serif", "monospace" };
        int namesLen = names.length;
        int numStyles = 4;
        FcCompFont[] fci = new FcCompFont[namesLen*numStyles];

        try {
            for (int i=0; i<namesLen; i++) {
                for (int s=0; s<numStyles; s++) {
                    int index = i*numStyles+s;
                    fci[index] = new FcCompFont();
                    String key = names[i]+"."+s;
                    fci[index].jdkName = names[i];
                    fci[index].fcFamily = fcnames[i];
                    fci[index].style = s;
                    String lenStr = (String)props.get(key+".length");
                    int nfonts = Integer.parseInt(lenStr);
                    if (nfonts <= 0) {
                        if (FontUtilities.debugFonts()) {
                            warning("bad non-positive .length entry in fontconfig file " + fcFile.toString());
                        }
                        return; // bad file
                    }
                    fci[index].allFonts = new FontConfigFont[nfonts];
                    for (int f=0; f<nfonts; f++) {
                        fci[index].allFonts[f] = new FontConfigFont();
                        String fkey = key+"."+f+".fullName";
                        String fullName = (String)props.get(fkey);
                        fci[index].allFonts[f].fullName = fullName;
                        fkey = key+"."+f+".file";
                        String file = (String)props.get(fkey);
                        if (file == null) {
                            if (FontUtilities.debugFonts()) {
                                warning("missing file value for key " + fkey + " in fontconfig file " + fcFile.toString());
                            }
                            return; // bad file
                        }
                        fci[index].allFonts[f].fontFile = file;
                    }
                    fci[index].firstFont =  fci[index].allFonts[0];

                }
            }
            fcCompFonts = fci;
        } catch (Throwable t) {
            if (FontUtilities.debugFonts()) {
                warning(t.toString());
            }
        }

        if (FontUtilities.debugFonts()) {
            FontUtilities.logInfo("successfully parsed the fontconfig file at " + fcFile.toString());
        }
    }

    private static void warning(String msg) {
        PlatformLogger logger = PlatformLogger.getLogger("sun.awt.FontConfiguration");
        logger.warning(msg);
    }
}
