/*
 * fontconfig/test/test-bz89617.c
 *
 * Copyright © 2000 Keith Packard
 * Copyright © 2018 Akira TAGOH
 *
 * 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.
 */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
#include <unistd.h>
#include <errno.h>
#ifndef HAVE_STRUCT_DIRENT_D_TYPE
#include <sys/types.h>
#include <sys/stat.h>
#endif
#include <fontconfig/fontconfig.h>

#ifdef _WIN32
#  define FC_DIR_SEPARATOR         '\\'
#  define FC_DIR_SEPARATOR_S       "\\"
#else
#  define FC_DIR_SEPARATOR         '/'
#  define FC_DIR_SEPARATOR_S       "/"
#endif

#ifdef _WIN32
#include <direct.h>
#define mkdir(path,mode) _mkdir(path)
#endif

#ifdef HAVE_MKDTEMP
#define fc_mkdtemp	mkdtemp
#else
char *
fc_mkdtemp (char *template)
{
    if (!mktemp (template) || mkdir (template, 0700))
	return NULL;

    return template;
}
#endif

FcBool
mkdir_p (const char *dir)
{
    char *parent;
    FcBool ret;

    if (strlen (dir) == 0)
	return FcFalse;
    parent = (char *) FcStrDirname ((const FcChar8 *) dir);
    if (!parent)
	return FcFalse;
    if (access (parent, F_OK) == 0)
	ret = mkdir (dir, 0755) == 0 && chmod (dir, 0755) == 0;
    else if (access (parent, F_OK) == -1)
	ret = mkdir_p (parent) && (mkdir (dir, 0755) == 0) && chmod (dir, 0755) == 0;
    else
	ret = FcFalse;
    free (parent);

    return ret;
}

FcBool
unlink_dirs (const char *dir)
{
    DIR *d = opendir (dir);
    struct dirent *e;
    size_t len = strlen (dir);
    char *n = NULL;
    FcBool ret = FcTrue;
#ifndef HAVE_STRUCT_DIRENT_D_TYPE
    struct stat statb;
#endif

    if (!d)
	return FcFalse;
    while ((e = readdir (d)) != NULL)
    {
	size_t l;

	if (strcmp (e->d_name, ".") == 0 ||
	    strcmp (e->d_name, "..") == 0)
	    continue;
	l = strlen (e->d_name) + 1;
	if (n)
	    free (n);
	n = malloc (l + len + 1);
	if (!n)
	{
	    ret = FcFalse;
	    break;
	}
	strcpy (n, dir);
	n[len] = FC_DIR_SEPARATOR;
	strcpy (&n[len + 1], e->d_name);
#ifdef HAVE_STRUCT_DIRENT_D_TYPE
	if (e->d_type == DT_DIR)
#else
	if (stat (n, &statb) == -1)
	{
	    fprintf (stderr, "E: %s\n", n);
	    ret = FcFalse;
	    break;
	}
	if (S_ISDIR (statb.st_mode))
#endif
	{
	    if (!unlink_dirs (n))
	    {
		fprintf (stderr, "E: %s\n", n);
		ret = FcFalse;
		break;
	    }
	}
	else
	{
	    if (unlink (n) == -1)
	    {
		fprintf (stderr, "E: %s\n", n);
		ret = FcFalse;
		break;
	    }
	}
    }
    if (n)
	free (n);
    closedir (d);

    if (rmdir (dir) == -1)
    {
	fprintf (stderr, "E: %s\n", dir);
	return FcFalse;
    }

    return ret;
}

int
main (void)
{
    FcChar8 *fontdir = NULL, *cachedir = NULL;
    char *basedir, template[512] = "/tmp/bz106632-XXXXXX";
    char cmd[512];
    FcConfig *config;
    const FcChar8 *tconf = (const FcChar8 *) "<fontconfig>\n"
	"  <dir>%s</dir>\n"
	"  <cachedir>%s</cachedir>\n"
	"</fontconfig>\n";
    char conf[1024];
    int ret = 0;
    FcFontSet *fs;
    FcPattern *pat;

    fprintf (stderr, "D: Creating tmp dir\n");
    basedir = fc_mkdtemp (template);
    if (!basedir)
    {
	fprintf (stderr, "%s: %s\n", template, strerror (errno));
	goto bail;
    }
    fontdir = FcStrBuildFilename ((const FcChar8 *) basedir, (const FcChar8 *) "fonts", NULL);
    cachedir = FcStrBuildFilename ((const FcChar8 *) basedir, (const FcChar8 *) "cache", NULL);
    fprintf (stderr, "D: Creating %s\n", fontdir);
    mkdir_p ((const char *) fontdir);
    fprintf (stderr, "D: Creating %s\n", cachedir);
    mkdir_p ((const char *) cachedir);

    fprintf (stderr, "D: Copying %s to %s\n", FONTFILE, fontdir);
    snprintf (cmd, 512, "sleep 1; cp -a %s %s; sleep 1", FONTFILE, fontdir);
    (void) system (cmd);

    fprintf (stderr, "D: Loading a config\n");
    snprintf (conf, 1024, (const char *) tconf, fontdir, cachedir);
    config = FcConfigCreate ();
    if (!FcConfigParseAndLoadFromMemory (config, (const FcChar8 *) conf, FcTrue))
    {
	printf ("E: Unable to load config\n");
	ret = 1;
	goto bail;
    }
    if (!FcConfigBuildFonts (config))
    {
	printf ("E: unable to build fonts\n");
	ret = 1;
	goto bail;
    }
    fprintf (stderr, "D: Obtaining fonts information\n");
    pat = FcPatternCreate ();
    fs = FcFontList (config, pat, NULL);
    FcPatternDestroy (pat);
    if (!fs || fs->nfont != 1)
    {
	printf ("E: Unexpected the number of fonts: %d\n", !fs ? -1 : fs->nfont);
	ret = 1;
	goto bail;
    }
    fprintf (stderr, "D: Removing %s\n", fontdir);
    snprintf (cmd, 512, "sleep 1; rm -f %s%s*; sleep 1", fontdir, FC_DIR_SEPARATOR_S);
    (void) system (cmd);
    fprintf (stderr, "D: Reinitializing\n");
    if (FcConfigUptoDate(config))
    {
	fprintf (stderr, "E: Config reports up-to-date\n");
	ret = 2;
	goto bail;
    }
    if (!FcInitReinitialize ())
    {
	fprintf (stderr, "E: Unable to reinitialize\n");
	ret = 3;
	goto bail;
    }
    if (FcConfigGetCurrent () == config)
    {
	fprintf (stderr, "E: config wasn't reloaded\n");
	ret = 3;
	goto bail;
    }
    config = FcConfigCreate ();
    if (!FcConfigParseAndLoadFromMemory (config, (const FcChar8 *) conf, FcTrue))
    {
	printf ("E: Unable to load config again\n");
	ret = 4;
	goto bail;
    }
    if (!FcConfigBuildFonts (config))
    {
	printf ("E: unable to build fonts again\n");
	ret = 5;
	goto bail;
    }
    fprintf (stderr, "D: Obtaining fonts information again\n");
    pat = FcPatternCreate ();
    fs = FcFontList (config, pat, NULL);
    FcPatternDestroy (pat);
    if (!fs || fs->nfont != 0)
    {
	printf ("E: Unexpected the number of fonts: %d\n", !fs ? -1 : fs->nfont);
	ret = 1;
	goto bail;
    }
    fprintf (stderr, "D: Copying %s to %s\n", FONTFILE, fontdir);
    snprintf (cmd, 512, "sleep 1; cp -a %s %s; sleep 1", FONTFILE, fontdir);
    (void) system (cmd);
    fprintf (stderr, "D: Reinitializing\n");
    if (FcConfigUptoDate(config))
    {
	fprintf (stderr, "E: Config up-to-date after addition\n");
	ret = 3;
	goto bail;
    }
    if (!FcInitReinitialize ())
    {
	fprintf (stderr, "E: Unable to reinitialize\n");
	ret = 2;
	goto bail;
    }
    if (FcConfigGetCurrent () == config)
    {
	fprintf (stderr, "E: config wasn't reloaded\n");
	ret = 3;
	goto bail;
    }
    config = FcConfigCreate ();
    if (!FcConfigParseAndLoadFromMemory (config, (const FcChar8 *) conf, FcTrue))
    {
	printf ("E: Unable to load config again\n");
	ret = 4;
	goto bail;
    }
    if (!FcConfigBuildFonts (config))
    {
	printf ("E: unable to build fonts again\n");
	ret = 5;
	goto bail;
    }
    fprintf (stderr, "D: Obtaining fonts information\n");
    pat = FcPatternCreate ();
    fs = FcFontList (config, pat, NULL);
    FcPatternDestroy (pat);
    if (!fs || fs->nfont != 1)
    {
	printf ("E: Unexpected the number of fonts: %d\n", !fs ? -1 : fs->nfont);
	ret = 1;
	goto bail;
    }

bail:
    fprintf (stderr, "Cleaning up\n");
    if (basedir)
	unlink_dirs (basedir);
    if (fontdir)
	FcStrFree (fontdir);
    if (cachedir)
	FcStrFree (cachedir);

    return ret;
}
