/*
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 */

#include <proton/scanner.h>
#include <proton/error.h>
#ifndef __cplusplus
#include <stdbool.h>
#endif
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "platform.h"

#define ERROR_SIZE (1024)

struct pn_scanner_t {
  const char *input;
  const char *position;
  pn_token_t token;
  char *atoms;
  size_t size;
  size_t capacity;
  pn_error_t *error;
};

static const char *pni_token_type(pn_token_type_t type)
{
  switch (type)
  {
  case PN_TOK_LBRACE: return "LBRACE";
  case PN_TOK_RBRACE: return "RBRACE";
  case PN_TOK_LBRACKET: return "LBRACKET";
  case PN_TOK_RBRACKET: return "RBRACKET";
  case PN_TOK_EQUAL: return "EQUAL";
  case PN_TOK_COMMA: return "COMMA";
  case PN_TOK_POS: return "POS";
  case PN_TOK_NEG: return "NEG";
  case PN_TOK_DOT: return "DOT";
  case PN_TOK_AT: return "AT";
  case PN_TOK_DOLLAR: return "DOLLAR";
  case PN_TOK_BINARY: return "BINARY";
  case PN_TOK_STRING: return "STRING";
  case PN_TOK_SYMBOL: return "SYMBOL";
  case PN_TOK_ID: return "ID";
  case PN_TOK_FLOAT: return "FLOAT";
  case PN_TOK_INT: return "INT";
  case PN_TOK_TRUE: return "TRUE";
  case PN_TOK_FALSE: return "FALSE";
  case PN_TOK_NULL: return "NULL";
  case PN_TOK_EOS: return "EOS";
  case PN_TOK_ERR: return "ERR";
  default: return "<UNKNOWN>";
  }
}

pn_scanner_t *pn_scanner()
{
  pn_scanner_t *scanner = (pn_scanner_t *) malloc(sizeof(pn_scanner_t));
  if (scanner) {
    scanner->input = NULL;
    scanner->error = pn_error();
  }
  return scanner;
}

void pn_scanner_free(pn_scanner_t *scanner)
{
  if (scanner) {
    pn_error_free(scanner->error);
    free(scanner);
  }
}

pn_token_t pn_scanner_token(pn_scanner_t *scanner)
{
  if (scanner) {
    return scanner->token;
  } else {
    pn_token_t tok = {PN_TOK_ERR, 0, (size_t)0};
    return tok;
  }
}

void pn_scanner_line_info(pn_scanner_t *scanner, int *line, int *col)
{
  *line = 1;
  *col = 0;

  for (const char *c = scanner->input; *c && c <= scanner->token.start; c++) {
    if (*c == '\n') {
      *line += 1;
      *col = -1;
    } else {
      *col += 1;
    }
  }
}

int pn_scanner_err(pn_scanner_t *scanner, int code, const char *fmt, ...)
{
  va_list ap;
  va_start(ap, fmt);
  int err = pn_scanner_verr(scanner, code, fmt, ap);
  va_end(ap);
  return err;
}

int pn_scanner_verr(pn_scanner_t *scanner, int code, const char *fmt, va_list ap)
{
  char error[ERROR_SIZE];

  int line, col;
  pn_scanner_line_info(scanner, &line, &col);
  int size = scanner->token.size;
  int ln = snprintf(error, ERROR_SIZE,
                    "input line %i column %i %s:'%.*s': ", line, col,
                    pni_token_type(scanner->token.type),
                    size, scanner->token.start);
  if (ln >= ERROR_SIZE) {
    return pn_scanner_err(scanner, code, "error info truncated");
  } else if (ln < 0) {
    error[0] = '\0';
  }

  int n = snprintf(error + ln, ERROR_SIZE - ln, fmt, ap);

  if (n >= ERROR_SIZE - ln) {
    return pn_scanner_err(scanner, code, "error info truncated");
  } else if (n < 0) {
    error[0] = '\0';
  }

  return pn_error_set(scanner->error, code, error);
}

int pn_scanner_errno(pn_scanner_t *scanner)
{
  return pn_error_code(scanner->error);
}

const char *pn_scanner_error(pn_scanner_t *scanner)
{
  return pn_error_text(scanner->error);
}

static void pni_scanner_emit(pn_scanner_t *scanner, pn_token_type_t type, const char *start, size_t size)
{
  scanner->token.type = type;
  scanner->token.start = start;
  scanner->token.size = size;
}

static int pni_scanner_quoted(pn_scanner_t *scanner, const char *str, int start,
                      pn_token_type_t type)
{
  bool escape = false;

  for (int i = start; true; i++) {
    char c = str[i];
    if (escape) {
      escape = false;
    } else {
      switch (c) {
      case '\0':
      case '"':
        pni_scanner_emit(scanner, c ? type : PN_TOK_ERR,
                        str, c ? i + 1 : i);
        return c ? 0 : pn_scanner_err(scanner, PN_ERR, "missmatched quote");
      case '\\':
        escape = true;
        break;
      }
    }
  }
}

static int pni_scanner_binary(pn_scanner_t *scanner, const char *str)
{
  return pni_scanner_quoted(scanner, str, 2, PN_TOK_BINARY);
}

static int pni_scanner_string(pn_scanner_t *scanner, const char *str)
{
  return pni_scanner_quoted(scanner, str, 1, PN_TOK_STRING);
}

static int pni_scanner_alpha_end(pn_scanner_t *scanner, const char *str, int start)
{
  for (int i = start; true; i++) {
    char c = str[i];
    if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))) {
      return i;
    }
  }
}

static int pni_scanner_alpha(pn_scanner_t *scanner, const char *str)
{
  int n = pni_scanner_alpha_end(scanner, str, 0);
  pn_token_type_t type;
  if (!strncmp(str, "true", n)) {
    type = PN_TOK_TRUE;
  } else if (!strncmp(str, "false", n)) {
    type = PN_TOK_FALSE;
  } else if (!strncmp(str, "null", n)) {
    type = PN_TOK_NULL;
  } else {
    type = PN_TOK_ID;
  }

  pni_scanner_emit(scanner, type, str, n);
  return type == PN_TOK_ERR ? pn_scanner_err(scanner, PN_ERR, "unrecognized keyword") : 0;
}

static int pni_scanner_symbol(pn_scanner_t *scanner, const char *str)
{
  char c = str[1];

  if (c == '"') {
    return pni_scanner_quoted(scanner, str, 2, PN_TOK_SYMBOL);
  } else {
    int n = pni_scanner_alpha_end(scanner, str, 1);
    pni_scanner_emit(scanner, PN_TOK_SYMBOL, str, n);
    return 0;
  }
}

static int pni_scanner_number(pn_scanner_t *scanner, const char *str)
{
  bool dot = false;
  bool exp = false;

  int i = 0;

  if (str[i] == '+' || str[i] == '-') {
    i++;
  }

  for ( ; true; i++) {
    char c = str[i];
    switch (c) {
    case '0': case '1': case '2': case '3': case '4': case '5': case '6':
    case '7': case '8': case '9':
      continue;
    case '.':
      if (dot) {
        pni_scanner_emit(scanner, PN_TOK_FLOAT, str, i);
        return 0;
      } else {
        dot = true;
      }
      continue;
    case 'e':
    case 'E':
      if (exp) {
        pni_scanner_emit(scanner, PN_TOK_FLOAT, str, i);
        return 0;
      } else {
        dot = true;
        exp = true;
        if (str[i+1] == '+' || str[i+1] == '-') {
          i++;
        }
        continue;
      }
    default:
      if (dot || exp) {
        pni_scanner_emit(scanner, PN_TOK_FLOAT, str, i);
        return 0;
      } else {
        pni_scanner_emit(scanner, PN_TOK_INT, str, i);
        return 0;
      }
    }
  }
}

static int pni_scanner_single(pn_scanner_t *scanner, const char *str, pn_token_type_t type)
{
  pni_scanner_emit(scanner, type, str, 1);
  return 0;
}

int pn_scanner_start(pn_scanner_t *scanner, const char *input)
{
  if (!scanner || !input) return PN_ARG_ERR;
  scanner->input = input;
  scanner->position = input;
  return pn_scanner_scan(scanner);
}

int pn_scanner_scan(pn_scanner_t *scanner)
{
  const char *str = scanner->position;
  char n;

  for (char c; true; str++) {
    c = *str;
    switch (c)
    {
    case '{':
      return pni_scanner_single(scanner, str, PN_TOK_LBRACE);
    case '}':
      return pni_scanner_single(scanner, str, PN_TOK_RBRACE);
    case'[':
      return pni_scanner_single(scanner, str, PN_TOK_LBRACKET);
    case ']':
      return pni_scanner_single(scanner, str, PN_TOK_RBRACKET);
    case '=':
      return pni_scanner_single(scanner, str, PN_TOK_EQUAL);
    case ',':
      return pni_scanner_single(scanner, str, PN_TOK_COMMA);
    case '.':
      n = *(str+1);
      if ((n >= '0' && n <= '9')) {
        return pni_scanner_number(scanner, str);
      } else {
        return pni_scanner_single(scanner, str, PN_TOK_DOT);
      }
    case '@':
      return pni_scanner_single(scanner, str, PN_TOK_AT);
    case '$':
      return pni_scanner_single(scanner, str, PN_TOK_DOLLAR);
    case '-':
      n = *(str+1);
      if ((n >= '0' && n <= '9') || n == '.') {
        return pni_scanner_number(scanner, str);
      } else {
        return pni_scanner_single(scanner, str, PN_TOK_NEG);
      }
    case '+':
      n = *(str+1);
      if ((n >= '0' && n <= '9') || n == '.') {
        return pni_scanner_number(scanner, str);
      } else {
        return pni_scanner_single(scanner, str, PN_TOK_POS);
      }
    case ' ': case '\t': case '\r': case '\v': case '\f': case '\n':
      break;
    case '0': case '1': case '2': case '3': case '4': case '5': case '6':
    case '7': case '8': case '9':
      return pni_scanner_number(scanner, str);
    case ':':
      return pni_scanner_symbol(scanner, str);
    case '"':
      return pni_scanner_string(scanner, str);
    case 'b':
      if (str[1] == '"') {
        return pni_scanner_binary(scanner, str);
      }
    case 'a': case 'c': case 'd': case 'e': case 'f': case 'g': case 'h':
    case 'i': case 'j': case 'k': case 'l': case 'm': case 'n': case 'o':
    case 'p': case 'q': case 'r': case 's': case 't': case 'u': case 'v':
    case 'w': case 'x': case 'y': case 'z': case 'A': case 'B': case 'C':
    case 'D': case 'E': case 'F': case 'G': case 'H': case 'I': case 'J':
    case 'K': case 'L': case 'M': case 'N': case 'O': case 'P': case 'Q':
    case 'R': case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
    case 'Y': case 'Z':
      return pni_scanner_alpha(scanner, str);
    case '\0':
      pni_scanner_emit(scanner, PN_TOK_EOS, str, 0);
      return PN_EOS;
    default:
      pni_scanner_emit(scanner, PN_TOK_ERR, str, 1);
      return pn_scanner_err(scanner, PN_ERR, "illegal character");
    }
  }
}

int pn_scanner_shift(pn_scanner_t *scanner)
{
  scanner->position = scanner->token.start + scanner->token.size;
  int err = pn_scanner_scan(scanner);
  if (err == PN_EOS) {
    return 0;
  } else {
    return err;
  }
}
