/*
 * fontconfig/fc-validate/fc-validate.c
 *
 * Copyright © 2003 Keith Packard
 * Copyright © 2012 Red Hat, Inc.
 * Red Hat Author(s): 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>
#else
#ifdef linux
#define HAVE_GETOPT_LONG 1
#endif
#define HAVE_GETOPT 1
#endif

#include <fontconfig/fontconfig.h>
#include <fontconfig/fcfreetype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <locale.h>

#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif

#ifdef ENABLE_NLS
#include <libintl.h>
#define _(x)		(dgettext(GETTEXT_PACKAGE, x))
#else
#define dgettext(d, s)	(s)
#define _(x)		(x)
#endif

#ifndef HAVE_GETOPT
#define HAVE_GETOPT 0
#endif
#ifndef HAVE_GETOPT_LONG
#define HAVE_GETOPT_LONG 0
#endif

#if HAVE_GETOPT_LONG
#undef  _GNU_SOURCE
#define _GNU_SOURCE
#include <getopt.h>
static const struct option longopts[] = {
    {"index", 1, 0, 'i'},
    {"lang", 1, 0, 'l'},
    {"verbose", 0, 0, 'v'},
    {"version", 0, 0, 'V'},
    {"help", 0, 0, 'h'},
    {NULL,0,0,0},
};
#else
#if HAVE_GETOPT
extern char *optarg;
extern int optind, opterr, optopt;
#endif
#endif

static void
usage (char *program, int error)
{
    FILE *file = error ? stderr : stdout;
#if HAVE_GETOPT_LONG
    fprintf (file, _("usage: %s [-Vhv] [-i index] [-l LANG] [--index index] [--lang LANG] [--verbose] [--version] [--help] font-file...\n"),
	     program);
#else
    fprintf (file, _("usage: %s [-Vhv] [-i index] [-l LANG] font-file...\n"),
	     program);
#endif
    fprintf (file, _("Validate font files and print result\n"));
    fprintf (file, "\n");
#if HAVE_GETOPT_LONG
    fprintf (file, _("  -i, --index INDEX    display the INDEX face of each font file only\n"));
    fprintf (file, _("  -l, --lang=LANG      set LANG instead of current locale\n"));
    fprintf (file, _("  -v, --verbose        show more detailed information\n"));
    fprintf (file, _("  -V, --version        display font config version and exit\n"));
    fprintf (file, _("  -h, --help           display this help and exit\n"));
#else
    fprintf (file, _("  -i INDEX   (index)        display the INDEX face of each font file only\n"));
    fprintf (file, _("  -l LANG    (lang)         set LANG instead of current locale\n"));
    fprintf (file, _("  -v         (verbose)      show more detailed information\n"));
    fprintf (file, _("  -V         (version)      display font config version and exit\n"));
    fprintf (file, _("  -h         (help)         display this help and exit\n"));
#endif
    exit (error);
}

int
main (int argc, char **argv)
{
    int		index_set = 0;
    int		set_index = 0;
    FcChar8     *lang = NULL;
    const FcCharSet *fcs_lang = NULL;
    int		err = 0;
    int		i;
    FT_Library  ftlib;
    FcBool      verbose = FcFalse;
#if HAVE_GETOPT_LONG || HAVE_GETOPT
    int		c;

    setlocale (LC_ALL, "");

#if HAVE_GETOPT_LONG
    while ((c = getopt_long (argc, argv, "i:l:mVhv", longopts, NULL)) != -1)
#else
    while ((c = getopt (argc, argv, "i:l:mVhv")) != -1)
#endif
    {
	switch (c) {
	case 'i':
	    index_set = 1;
	    set_index = atoi (optarg);
	    break;
	case 'l':
	    lang = (FcChar8 *) FcLangNormalize ((const FcChar8 *) optarg);
	    break;
	case 'v':
	    verbose = FcTrue;
	    break;
	case 'V':
	    fprintf (stderr, "fontconfig version %d.%d.%d\n",
		     FC_MAJOR, FC_MINOR, FC_REVISION);
	    exit (0);
	case 'h':
	    usage (argv[0], 0);
	default:
	    usage (argv[0], 1);
	}
    }
    i = optind;
#else
    i = 1;
    verbose = FcTrue;
#endif

    if (i == argc)
	usage (argv[0], 1);

    if (!lang)
	lang = FcLangNormalize ((const FcChar8 *) setlocale (LC_CTYPE, NULL));

    if (lang)
	fcs_lang = FcLangGetCharSet (lang);

    if (FT_Init_FreeType (&ftlib))
    {
	fprintf (stderr, _("Can't initialize FreeType library\n"));
	return 1;
    }

    for (; i < argc; i++)
    {
	int index;

	index = set_index;

	do {
	    FT_Face face;
	    FcCharSet *fcs, *fcs_sub;

	    if (FT_New_Face (ftlib, argv[i], index, &face))
	    {
		if (!index_set && index > 0)
		    break;
		fprintf (stderr, _("Unable to open %s\n"), argv[i]);
		err = 1;
	    }
	    else
	    {
		FcChar32 count;

		fcs = FcFreeTypeCharSet (face, NULL);
		fcs_sub = FcCharSetSubtract (fcs_lang, fcs);

		count = FcCharSetCount (fcs_sub);
		if (count > 0)
		{
		    FcChar32 ucs4, pos, map[FC_CHARSET_MAP_SIZE];

		    err = 1;
		    printf (_("%s:%d Missing %d glyph(s) to satisfy the coverage for %s language\n"),
			    argv[i], index, count, lang);

		    if (verbose)
		    {
			for (ucs4 = FcCharSetFirstPage (fcs_sub, map, &pos);
			     ucs4 != FC_CHARSET_DONE;
			     ucs4 = FcCharSetNextPage (fcs_sub, map, &pos))
			{
			    int j;

			    for (j = 0; j < FC_CHARSET_MAP_SIZE; j++)
			    {
				FcChar32 bits = map[j];
				FcChar32 base = ucs4 + j * 32;
				int b = 0;

				while (bits)
				{
				    if (bits & 1)
					printf ("  0x%04x\n", base + b);
				    bits >>= 1;
				    b++;
				}
			    }
			}
		    }
		}
		else
		{
		    printf (_("%s:%d Satisfy the coverage for %s language\n"), argv[i], index, lang);
		}

		FcCharSetDestroy (fcs);
		FcCharSetDestroy (fcs_sub);

		FT_Done_Face (face);
	    }

	    index++;
	} while (index_set == 0);
    }

    FT_Done_FreeType (ftlib);

    if (lang)
	FcStrFree (lang);

    FcFini ();
    return err;
}
