// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc.  All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include "names.h"

#include <stdlib.h>

#include "protobuf.h"

/* stringsink *****************************************************************/

typedef struct {
  char *ptr;
  size_t len, size;
} stringsink;

static size_t stringsink_string(stringsink *sink, const char *ptr, size_t len) {
  size_t new_size = sink->size;

  while (sink->len + len > new_size) {
    new_size *= 2;
  }

  if (new_size != sink->size) {
    sink->ptr = realloc(sink->ptr, new_size);
    sink->size = new_size;
  }

  memcpy(sink->ptr + sink->len, ptr, len);
  sink->len += len;

  return len;
}

static void stringsink_init(stringsink *sink) {
  sink->size = 32;
  sink->ptr = malloc(sink->size);
  PBPHP_ASSERT(sink->ptr != NULL);
  sink->len = 0;
}

static void stringsink_uninit(stringsink *sink) { free(sink->ptr); }

/* def name -> classname ******************************************************/

const char *const kReservedNames[] = {
    "abstract",   "and",        "array",        "as",           "break",
    "callable",   "case",       "catch",        "class",        "clone",
    "const",      "continue",   "declare",      "default",      "die",
    "do",         "echo",       "else",         "elseif",       "empty",
    "enddeclare", "endfor",     "endforeach",   "endif",        "endswitch",
    "endwhile",   "eval",       "exit",         "extends",      "final",
    "for",        "foreach",    "function",     "global",       "goto",
    "if",         "implements", "include",      "include_once", "instanceof",
    "insteadof",  "interface",  "isset",        "list",         "namespace",
    "new",        "or",         "print",        "private",      "protected",
    "public",     "require",    "require_once", "return",       "static",
    "switch",     "throw",      "trait",        "try",          "unset",
    "use",        "var",        "while",        "xor",          "int",
    "float",      "bool",       "string",       "true",         "false",
    "null",       "void",       "iterable",     NULL};

bool is_reserved_name(const char* name) {
  int i;
  for (i = 0; kReservedNames[i]; i++) {
    if (strcmp(kReservedNames[i], name) == 0) {
      return true;
    }
  }
  return false;
}

static char nolocale_tolower(char ch) {
  if (ch >= 'A' && ch <= 'Z') {
    return ch - ('A' - 'a');
  } else {
    return ch;
  }
}

static char nolocale_toupper(char ch) {
  if (ch >= 'a' && ch <= 'z') {
    return ch - ('a' - 'A');
  } else {
    return ch;
  }
}

static bool is_reserved(const char *segment, int length) {
  bool result;
  char* lower = calloc(1, length + 1);
  memcpy(lower, segment, length);
  int i = 0;
  while(lower[i]) {
    lower[i] = nolocale_tolower(lower[i]);
    i++;
  }
  lower[length] = 0;
  result = is_reserved_name(lower);
  free(lower);
  return result;
}

static void fill_prefix(const char *segment, int length,
                        const char *prefix_given,
                        const char *package_name,
                        stringsink *classname) {
  if (prefix_given != NULL && strcmp(prefix_given, "") != 0) {
    stringsink_string(classname, prefix_given, strlen(prefix_given));
  } else {
    if (is_reserved(segment, length)) {
      if (package_name != NULL &&
          strcmp("google.protobuf", package_name) == 0) {
        stringsink_string(classname, "GPB", 3);
      } else {
        stringsink_string(classname, "PB", 2);
      }
    }
  }
}

static void fill_segment(const char *segment, int length,
                         stringsink *classname, bool use_camel) {
  if (use_camel && (segment[0] < 'A' || segment[0] > 'Z')) {
    char first = nolocale_toupper(segment[0]);
    stringsink_string(classname, &first, 1);
    stringsink_string(classname, segment + 1, length - 1);
  } else {
    stringsink_string(classname, segment, length);
  }
}

static void fill_namespace(const char *package, const char *php_namespace,
                           stringsink *classname) {
  if (php_namespace != NULL) {
    if (strlen(php_namespace) != 0) {
      stringsink_string(classname, php_namespace, strlen(php_namespace));
      stringsink_string(classname, "\\", 1);
    }
  } else if (package != NULL) {
    int i = 0, j = 0;
    size_t package_len = strlen(package);
    while (i < package_len) {
      j = i;
      while (j < package_len && package[j] != '.') {
        j++;
      }
      fill_prefix(package + i, j - i, "", package, classname);
      fill_segment(package + i, j - i, classname, true);
      stringsink_string(classname, "\\", 1);
      i = j + 1;
    }
  }
}

static void fill_classname(const char *fullname,
                           const char *package,
                           const char *prefix,
                           stringsink *classname) {
  int classname_start = 0;
  if (package != NULL) {
    size_t package_len = strlen(package);
    classname_start = package_len == 0 ? 0 : package_len + 1;
  }
  size_t fullname_len = strlen(fullname);

  int i = classname_start, j;
  while (i < fullname_len) {
    j = i;
    while (j < fullname_len && fullname[j] != '.') {
      j++;
    }
    fill_prefix(fullname + i, j - i, prefix, package, classname);
    fill_segment(fullname + i, j - i, classname, false);
    if (j != fullname_len) {
      stringsink_string(classname, "\\", 1);
    }
    i = j + 1;
  }
}

char *GetPhpClassname(const upb_filedef *file, const char *fullname) {
  // Prepend '.' to package name to make it absolute. In the 5 additional
  // bytes allocated, one for '.', one for trailing 0, and 3 for 'GPB' if
  // given message is google.protobuf.Empty.
  const char *package = upb_filedef_package(file);
  const char *php_namespace = upb_filedef_phpnamespace(file);
  const char *prefix = upb_filedef_phpprefix(file);
  char *ret;
  stringsink namesink;
  stringsink_init(&namesink);

  fill_namespace(package, php_namespace, &namesink);
  fill_classname(fullname, package, prefix, &namesink);
  stringsink_string(&namesink, "\0", 1);
  ret = strdup(namesink.ptr);
  stringsink_uninit(&namesink);
  return ret;
}
