/*
 * 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 initalize 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;
}
