/*
 *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */


#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include "args.h"

#ifdef _MSC_VER
#define snprintf _snprintf
#endif

#if defined(__GNUC__) && __GNUC__
extern void die(const char *fmt, ...) __attribute__((noreturn));
#else
extern void die(const char *fmt, ...);
#endif


struct arg arg_init(char **argv)
{
    struct arg a;

    a.argv      = argv;
    a.argv_step = 1;
    a.name      = NULL;
    a.val       = NULL;
    a.def       = NULL;
    return a;
}

int arg_match(struct arg *arg_, const struct arg_def *def, char **argv)
{
    struct arg arg;

    if (!argv[0] || argv[0][0] != '-')
        return 0;

    arg = arg_init(argv);

    if (def->short_name
        && strlen(arg.argv[0]) == strlen(def->short_name) + 1
        && !strcmp(arg.argv[0] + 1, def->short_name))
    {

        arg.name = arg.argv[0] + 1;
        arg.val = def->has_val ? arg.argv[1] : NULL;
        arg.argv_step = def->has_val ? 2 : 1;
    }
    else if (def->long_name)
    {
        const size_t name_len = strlen(def->long_name);

        if (strlen(arg.argv[0]) >= name_len + 2
            && arg.argv[0][1] == '-'
            && !strncmp(arg.argv[0] + 2, def->long_name, name_len)
            && (arg.argv[0][name_len+2] == '='
                || arg.argv[0][name_len+2] == '\0'))
        {

            arg.name = arg.argv[0] + 2;
            arg.val = arg.name[name_len] == '=' ? arg.name + name_len + 1 : NULL;
            arg.argv_step = 1;
        }
    }

    if (arg.name && !arg.val && def->has_val)
        die("Error: option %s requires argument.\n", arg.name);

    if (arg.name && arg.val && !def->has_val)
        die("Error: option %s requires no argument.\n", arg.name);

    if (arg.name
        && (arg.val || !def->has_val))
    {
        arg.def = def;
        *arg_ = arg;
        return 1;
    }

    return 0;
}


const char *arg_next(struct arg *arg)
{
    if (arg->argv[0])
        arg->argv += arg->argv_step;

    return *arg->argv;
}


char **argv_dup(int argc, const char **argv)
{
    char **new_argv = malloc((argc + 1) * sizeof(*argv));

    memcpy(new_argv, argv, argc * sizeof(*argv));
    new_argv[argc] = NULL;
    return new_argv;
}


void arg_show_usage(FILE *fp, const struct arg_def *const *defs)
{
    char option_text[40] = {0};

    for (; *defs; defs++)
    {
        const struct arg_def *def = *defs;
        char *short_val = def->has_val ? " <arg>" : "";
        char *long_val = def->has_val ? "=<arg>" : "";

        if (def->short_name && def->long_name)
        {
            char *comma = def->has_val ? "," : ",      ";

            snprintf(option_text, 37, "-%s%s%s --%s%6s",
                     def->short_name, short_val, comma,
                     def->long_name, long_val);
        }
        else if (def->short_name)
            snprintf(option_text, 37, "-%s%s",
                     def->short_name, short_val);
        else if (def->long_name)
            snprintf(option_text, 37, "          --%s%s",
                     def->long_name, long_val);

        fprintf(fp, "  %-37s\t%s\n", option_text, def->desc);

        if(def->enums)
        {
            const struct arg_enum_list *listptr;

            fprintf(fp, "  %-37s\t  ", "");

            for(listptr = def->enums; listptr->name; listptr++)
                fprintf(fp, "%s%s", listptr->name,
                        listptr[1].name ? ", " : "\n");
        }
    }
}


unsigned int arg_parse_uint(const struct arg *arg)
{
    long int   rawval;
    char      *endptr;

    rawval = strtol(arg->val, &endptr, 10);

    if (arg->val[0] != '\0' && endptr[0] == '\0')
    {
        if (rawval >= 0 && rawval <= UINT_MAX)
            return rawval;

        die("Option %s: Value %ld out of range for unsigned int\n",
            arg->name, rawval);
    }

    die("Option %s: Invalid character '%c'\n", arg->name, *endptr);
    return 0;
}


int arg_parse_int(const struct arg *arg)
{
    long int   rawval;
    char      *endptr;

    rawval = strtol(arg->val, &endptr, 10);

    if (arg->val[0] != '\0' && endptr[0] == '\0')
    {
        if (rawval >= INT_MIN && rawval <= INT_MAX)
            return rawval;

        die("Option %s: Value %ld out of range for signed int\n",
            arg->name, rawval);
    }

    die("Option %s: Invalid character '%c'\n", arg->name, *endptr);
    return 0;
}


struct vpx_rational
{
    int num; /**< fraction numerator */
    int den; /**< fraction denominator */
};
struct vpx_rational arg_parse_rational(const struct arg *arg)
{
    long int             rawval;
    char                *endptr;
    struct vpx_rational  rat;

    /* parse numerator */
    rawval = strtol(arg->val, &endptr, 10);

    if (arg->val[0] != '\0' && endptr[0] == '/')
    {
        if (rawval >= INT_MIN && rawval <= INT_MAX)
            rat.num = rawval;
        else die("Option %s: Value %ld out of range for signed int\n",
                     arg->name, rawval);
    }
    else die("Option %s: Expected / at '%c'\n", arg->name, *endptr);

    /* parse denominator */
    rawval = strtol(endptr + 1, &endptr, 10);

    if (arg->val[0] != '\0' && endptr[0] == '\0')
    {
        if (rawval >= INT_MIN && rawval <= INT_MAX)
            rat.den = rawval;
        else die("Option %s: Value %ld out of range for signed int\n",
                     arg->name, rawval);
    }
    else die("Option %s: Invalid character '%c'\n", arg->name, *endptr);

    return rat;
}


int arg_parse_enum(const struct arg *arg)
{
    const struct arg_enum_list *listptr;
    long int                    rawval;
    char                       *endptr;

    /* First see if the value can be parsed as a raw value */
    rawval = strtol(arg->val, &endptr, 10);
    if (arg->val[0] != '\0' && endptr[0] == '\0')
    {
        /* Got a raw value, make sure it's valid */
        for(listptr = arg->def->enums; listptr->name; listptr++)
            if(listptr->val == rawval)
                return rawval;
    }

    /* Next see if it can be parsed as a string */
    for(listptr = arg->def->enums; listptr->name; listptr++)
        if(!strcmp(arg->val, listptr->name))
            return listptr->val;

    die("Option %s: Invalid value '%s'\n", arg->name, arg->val);
    return 0;
}


int arg_parse_enum_or_int(const struct arg *arg)
{
    if(arg->def->enums)
        return arg_parse_enum(arg);
    return arg_parse_int(arg);
}
