/*
 * Copyright (c) 2020 MediaTek Inc.
 *
 * Use of this source code is governed by a MIT-style
 * license that can be found in the LICENSE file or at
 * https://opensource.org/licenses/MIT
 */

#include <assert.h>
#include <ctype.h>
#include <debug.h>
#include <limits.h>
#include <platform/debug.h>
#include <printf.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <trace.h>

#define LOCAL_TRACE 0

#define FLAG_SHORT      (0x1 << 2)
#define FLAG_INT        (0x1 << 3)

static int xchar_to_int(char c)
{
    if (isdigit(c))
        return c - '0';
    else if (c >= 'a' && c <= 'f')
        return 10 + c - 'a';
    else if (c >= 'A' && c <= 'F')
        return 10 + c - 'A';
    else
        return 0;   // not xdigit: return 0!
}

static int get_int(const char **buf, int *val)
{
    const char *p = *buf;
    int i = 0;
    int err = -1;
    int sign = 0;

    // ignore blank
    while (isspace(*p)) {
        ++p;
    }

    if (*p == '+')
        ++p;
    else if (*p == '-') {
        sign = 1;
        ++p;
    }

    while (1) {
        char c = *p;

        if (isdigit(c)) {
            i = i * 10 + (c - '0');
            err = 0;        // find at least one digit

            LTRACEF("buf:%s, i:%d, c:%c\n", p, i, c);

            ++p;
            continue;
        } else {
            if (err == -1)
                return -1;

            *buf = p;

            *val = sign ? -i : i;
            break;
        }
    }

    return 0;
}

static int get_hex_int(const char **buf)
{
    const char *p = *buf;
    int i = 0;
    int err = -1;
    int found_hex_prefix = 0, ignore_hex_prefix = 0;

    // ignore blank
    while (isspace(*p)) {
        ++p;
    }

    while (1) {
        char c = *p;

        if (isspace(c)) {
            *buf = p;
            break;
        }

        // hex prefix
        if (!ignore_hex_prefix && !found_hex_prefix && c == '0') {
            c = *++p;
            if (c == 'x' || c == 'X') {
                found_hex_prefix = 1;
                ignore_hex_prefix = 1;
                ++p;
                continue;
            } else if (isxdigit(c)) {
                i = i * 16 + (xchar_to_int(c));
                ignore_hex_prefix = 1;
                ++p;
            } else
                goto error;
        }

        if (isxdigit(c)) {
            i = i * 16 + xchar_to_int(c);
            ignore_hex_prefix = 1;
            err = 0;        // find at least one digit

            LTRACEF("buf:%s, i:0x%x, c:%c\n", p, i, c);

            ++p;
            continue;
        } else if (err == 0)
            break;
        else
            goto error;
    }

    if (err == 0)
        *buf = p;
    return i;

error:
    return -1;
}

/* support interger scanf  */
static int vsscanf(const char *buf, const char *fmt, va_list ap)
{
    int err = 0;
    char c;
    size_t item;
    int n;
    int *p;
    char *pch;
    short *psh;
    int flag;

    item = 0;
    flag = FLAG_INT;

    for (;;) {
        while ((c = *fmt++) != 0) {
            if (isspace(c))
                continue;

            if (c == '%')
                break;
            else {
                while (isspace(*buf)) {
                    ++buf;
                }
                if (c != *buf)
                    return 0;

                ++buf;
            }
        }

        /* make sure we haven't just hit the end of the string */
        if (c == 0)
            break;

        c = *fmt++;
        if (c == 0)
            break;

format_continue:
        switch (c) {
            case 'h':   /* short interger: %hd */
                flag = FLAG_SHORT;
                c = *fmt++;
                goto format_continue;
            case 'd':   /* interger: %d */
                if (flag == FLAG_SHORT)
                    psh = va_arg(ap, short *);
                else
                    p = va_arg(ap, int *);

                err = get_int(&buf, &n);

                if (err < 0)
                    goto exit;

                if (flag == FLAG_SHORT)
                    *psh = n;
                else
                    *p = n;
                item++;
                break;

            case 'x':  /* hex interger */
            case 'X':
                p = va_arg(ap, int *);

                n = get_hex_int(&buf);

                if (n < 0)
                    goto exit;

                *p = n;
                item++;
                break;

            default:
                err = -1;
                break;
        }

        continue;
    }

exit:
    return (err < 0) ? 0 : (int)item;
}

// a simple sscanf: %d, %x
int sscanf(const char *buf, const char *fmt, ...)
{
    va_list ap;
    int err;

    va_start(ap, fmt);
    err = vsscanf(buf, fmt, ap);
    va_end(ap);

    return err;
}

