/*
 * fontconfig/src/fcdir.c
 *
 * Copyright © 2000 Keith Packard
 *
 * Permission to use, copy, modify, distribute, and sell this software and its
 * documentation for any purpose is hereby granted without fee, provided that
 * the above copyright notice appear in all copies and that both that
 * copyright notice and this permission notice appear in supporting
 * documentation, and that the name of the author(s) not be used in
 * advertising or publicity pertaining to distribution of the software without
 * specific, written prior permission.  The authors make no
 * representations about the suitability of this software for any purpose.  It
 * is provided "as is" without express or implied warranty.
 *
 * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 * EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 * PERFORMANCE OF THIS SOFTWARE.
 */

#include "fcint.h"
#include "fcftint.h"
#include <ft2build.h>
#include FT_FREETYPE_H
#include <dirent.h>

FcBool
FcFileIsDir (const FcChar8 *file)
{
    struct stat	    statb;

    if (FcStat (file, &statb) != 0)
	return FcFalse;
    return S_ISDIR(statb.st_mode);
}

FcBool
FcFileIsLink (const FcChar8 *file)
{
#if HAVE_LSTAT
    struct stat statb;

    if (lstat ((const char *)file, &statb) != 0)
	return FcFalse;
    return S_ISLNK (statb.st_mode);
#else
    return FcFalse;
#endif
}

FcBool
FcFileIsFile (const FcChar8 *file)
{
    struct stat statb;

    if (FcStat (file, &statb) != 0)
	return FcFalse;
    return S_ISREG (statb.st_mode);
}

static FcBool
FcFileScanFontConfig (FcFontSet		*set,
		      FcBlanks		*blanks,
		      const FcChar8	*file,
		      FcConfig		*config)
{
    FT_Library	ftLibrary;
    FT_Face	face;
    FcPattern	*font;
    FcBool	ret = FcTrue;
    int		num_faces = 0;
    int		num_instances = 0;
    int		face_num = 0;
    int		instance_num = 0;
    int		id;
    const FcChar8 *sysroot = FcConfigGetSysRoot (config);

    if (FT_Init_FreeType (&ftLibrary))
	return FcFalse;

    do
    {
	font = 0;
	/*
	 * Nothing in the cache, scan the file
	 */
	if (FcDebug () & FC_DBG_SCAN)
	{
	    printf ("\tScanning file %s...", file);
	    fflush (stdout);
	}

	id = ((instance_num << 16) + face_num);
	if (FT_New_Face (ftLibrary, (char *) file, id, &face))
	    return FcFalse;
	num_faces = face->num_faces;
	num_instances = face->style_flags >> 16;
	font = FcFreeTypeQueryFace (face, file, id, blanks);
	FT_Done_Face (face);

	if (FcDebug () & FC_DBG_SCAN)
	    printf ("done\n");
	/*
	 * Get rid of sysroot here so that targeting scan rule may contains FC_FILE pattern
	 * and they should usually expect without sysroot.
	 */
	if (font && sysroot)
	{
	    size_t len = strlen ((const char *)sysroot);
	    FcChar8 *f = NULL;

	    if (FcPatternObjectGetString (font, FC_FILE_OBJECT, 0, &f) == FcResultMatch &&
		strncmp ((const char *)f, (const char *)sysroot, len) == 0)
	    {
		FcChar8 *s = FcStrdup (f);
		FcPatternObjectDel (font, FC_FILE_OBJECT);
		if (s[len] != '/')
		    len--;
		else if (s[len+1] == '/')
		    len++;
		FcPatternObjectAddString (font, FC_FILE_OBJECT, &s[len]);
		FcStrFree (s);
	    }
	}

	/*
	 * Edit pattern with user-defined rules
	 */
	if (font && config && !FcConfigSubstitute (config, font, FcMatchScan))
	{
	    FcPatternDestroy (font);
	    font = NULL;
	    ret = FcFalse;
	}

	/*
	 * Add the font
	 */
	if (font)
	{
	    if (FcDebug() & FC_DBG_SCANV)
	    {
		printf ("Final font pattern:\n");
		FcPatternPrint (font);
	    }
	    if (!FcFontSetAdd (set, font))
	    {
		FcPatternDestroy (font);
		font = NULL;
		ret = FcFalse;
	    }
	}
	else
	    ret = FcFalse;

	if (instance_num < num_instances)
	    instance_num++;
	else
	{
	    face_num++;
	    instance_num = 0;
	}
    } while (font && ret && face_num < num_faces);

    FT_Done_FreeType (ftLibrary);

    return ret;
}

FcBool
FcFileScanConfig (FcFontSet	*set,
		  FcStrSet	*dirs,
		  FcBlanks	*blanks,
		  const FcChar8	*file,
		  FcConfig	*config)
{
    if (FcFileIsDir (file))
    {
	const FcChar8 *sysroot = FcConfigGetSysRoot (config);
	const FcChar8 *d = file;
	size_t len;

	if (sysroot)
	{
		len = strlen ((const char *)sysroot);
		if (strncmp ((const char *)file, (const char *)sysroot, len) == 0)
		{
			if (file[len] != '/')
				len--;
			else if (file[len+1] == '/')
				len++;
			d = &file[len];
		}
	}
	return FcStrSetAdd (dirs, d);
    }
    else
    {
	if (set)
	    return FcFileScanFontConfig (set, blanks, file, config);
	else
	    return FcTrue;
    }
}

FcBool
FcFileScan (FcFontSet	    *set,
	    FcStrSet	    *dirs,
	    FcFileCache	    *cache FC_UNUSED,
	    FcBlanks	    *blanks,
	    const FcChar8   *file,
	    FcBool	    force FC_UNUSED)
{
    return FcFileScanConfig (set, dirs, blanks, file, FcConfigGetCurrent ());
}

/*
 * Strcmp helper that takes pointers to pointers, copied from qsort(3) manpage
 */
static int
cmpstringp(const void *p1, const void *p2)
{
    return strcmp(* (char **) p1, * (char **) p2);
}

FcBool
FcDirScanConfig (FcFontSet	*set,
		 FcStrSet	*dirs,
		 FcBlanks	*blanks,
		 const FcChar8	*dir,
		 FcBool		force, /* XXX unused */
		 FcConfig	*config)
{
    DIR			*d;
    struct dirent	*e;
    FcStrSet		*files;
    FcChar8		*file;
    FcChar8		*base;
    FcBool		ret = FcTrue;
    int			i;

    if (!force)
	return FcFalse;

    if (!set && !dirs)
	return FcTrue;

    if (!blanks)
	blanks = FcConfigGetBlanks (config);

    /* freed below */
    file = (FcChar8 *) malloc (strlen ((char *) dir) + 1 + FC_MAX_FILE_LEN + 1);
    if (!file) {
	ret = FcFalse;
	goto bail;
    }

    strcpy ((char *) file, (char *) dir);
    strcat ((char *) file, "/");
    base = file + strlen ((char *) file);

    if (FcDebug () & FC_DBG_SCAN)
	printf ("\tScanning dir %s\n", dir);
	
    d = opendir ((char *) dir);
    if (!d)
    {
	/* Don't complain about missing directories */
	if (errno != ENOENT)
	    ret = FcFalse;
	goto bail;
    }

    files = FcStrSetCreateEx (FCSS_ALLOW_DUPLICATES | FCSS_GROW_BY_64);
    if (!files)
    {
	ret = FcFalse;
	goto bail1;
    }
    while ((e = readdir (d)))
    {
	if (e->d_name[0] != '.' && strlen (e->d_name) < FC_MAX_FILE_LEN)
	{
	    strcpy ((char *) base, (char *) e->d_name);
	    if (!FcStrSetAdd (files, file)) {
		ret = FcFalse;
		goto bail2;
	    }
	}
    }

    /*
     * Sort files to make things prettier
     */
    qsort(files->strs, files->num, sizeof(FcChar8 *), cmpstringp);

    /*
     * Scan file files to build font patterns
     */
    for (i = 0; i < files->num; i++)
	FcFileScanConfig (set, dirs, blanks, files->strs[i], config);

bail2:
    FcStrSetDestroy (files);
bail1:
    closedir (d);
bail:
    if (file)
	free (file);

    return ret;
}

FcBool
FcDirScan (FcFontSet	    *set,
	   FcStrSet	    *dirs,
	   FcFileCache	    *cache, /* XXX unused */
	   FcBlanks	    *blanks,
	   const FcChar8    *dir,
	   FcBool	    force /* XXX unused */)
{
    if (cache || !force)
	return FcFalse;

    return FcDirScanConfig (set, dirs, blanks, dir, force, FcConfigGetCurrent ());
}

/*
 * Scan the specified directory and construct a cache of its contents
 */
FcCache *
FcDirCacheScan (const FcChar8 *dir, FcConfig *config)
{
    FcStrSet		*dirs;
    FcFontSet		*set;
    FcCache		*cache = NULL;
    struct stat		dir_stat;
    const FcChar8	*sysroot = FcConfigGetSysRoot (config);
    FcChar8		*d;
    int			fd = -1;

    if (sysroot)
	d = FcStrBuildFilename (sysroot, dir, NULL);
    else
	d = FcStrdup (dir);

    if (FcDebug () & FC_DBG_FONTSET)
	printf ("cache scan dir %s\n", d);

    if (FcStatChecksum (d, &dir_stat) < 0)
	goto bail;

    set = FcFontSetCreate();
    if (!set)
	goto bail;

    dirs = FcStrSetCreateEx (FCSS_GROW_BY_64);
    if (!dirs)
	goto bail1;

#ifndef _WIN32
    fd = FcDirCacheLock (dir, config);
#endif
    /*
     * Scan the dir
     */
    if (!FcDirScanConfig (set, dirs, NULL, d, FcTrue, config))
	goto bail2;

    /*
     * Build the cache object
     */
    cache = FcDirCacheBuild (set, dir, &dir_stat, dirs);
    if (!cache)
	goto bail2;

    /*
     * Write out the cache file, ignoring any troubles
     */
    FcDirCacheWrite (cache, config);

 bail2:
#ifndef _WIN32
    FcDirCacheUnlock (fd);
#endif
    FcStrSetDestroy (dirs);
 bail1:
    FcFontSetDestroy (set);
 bail:
    FcStrFree (d);

    return cache;
}

FcCache *
FcDirCacheRescan (const FcChar8 *dir, FcConfig *config)
{
    FcCache *cache;
    FcCache *new = NULL;
    struct stat dir_stat;
    FcStrSet *dirs;
    const FcChar8 *sysroot = FcConfigGetSysRoot (config);
    FcChar8 *d = NULL;
    int fd = -1;

    cache = FcDirCacheLoad (dir, config, NULL);
    if (!cache)
	goto bail;

    if (sysroot)
	d = FcStrBuildFilename (sysroot, dir, NULL);
    else
	d = FcStrdup (dir);
    if (FcStatChecksum (d, &dir_stat) < 0)
	goto bail;
    dirs = FcStrSetCreateEx (FCSS_GROW_BY_64);
    if (!dirs)
	goto bail;

#ifndef _WIN32
    fd = FcDirCacheLock (dir, config);
#endif
    /*
     * Scan the dir
     */
    if (!FcDirScanConfig (NULL, dirs, NULL, d, FcTrue, config))
	goto bail1;
    /*
     * Rebuild the cache object
     */
    new = FcDirCacheRebuild (cache, &dir_stat, dirs);
    if (!new)
	goto bail1;
    FcDirCacheUnload (cache);
    /*
     * Write out the cache file, ignoring any troubles
     */
    FcDirCacheWrite (new, config);

bail1:
#ifndef _WIN32
    FcDirCacheUnlock (fd);
#endif
    FcStrSetDestroy (dirs);
bail:
    if (d)
	FcStrFree (d);

    return new;
}

/*
 * Read (or construct) the cache for a directory
 */
FcCache *
FcDirCacheRead (const FcChar8 *dir, FcBool force, FcConfig *config)
{
    FcCache		*cache = NULL;

    /* Try to use existing cache file */
    if (!force)
	cache = FcDirCacheLoad (dir, config, NULL);

    /* Not using existing cache file, construct new cache */
    if (!cache)
	cache = FcDirCacheScan (dir, config);

    return cache;
}

FcBool
FcDirSave (FcFontSet *set FC_UNUSED, FcStrSet * dirs FC_UNUSED, const FcChar8 *dir FC_UNUSED)
{
    return FcFalse; /* XXX deprecated */
}
#define __fcdir__
#include "fcaliastail.h"
#undef __fcdir__
