/* -----------------------------------------------------------------------------
 * This file is part of SWIG, which is licensed as a whole under version 3 
 * (or any later version) of the GNU General Public License. Some additional
 * terms also apply to certain portions of SWIG. The full details of the SWIG
 * license and copyrights can be found in the LICENSE and COPYRIGHT files
 * included with the SWIG source code as distributed by the SWIG developers
 * and at https://www.swig.org/legal.html.
 *
 * nested.cxx
 *
 * Nested structs support
 * ----------------------------------------------------------------------------- */

#include "swigmod.h"
#include "cparse.h"

// Nested classes processing section
static Hash *classhash = 0;

static String *make_name(Node *n, String *name, SwigType *decl) {
  int destructor = name && (*(Char(name)) == '~');
  if (String *yyrename = Getattr(n, "class_rename")) {
    String *s = NewString(yyrename);
    Delattr(n, "class_rename");
    if (destructor && (*(Char(s)) != '~')) {
      Insert(s, 0, "~");
    }
    return s;
  }

  if (!name)
    return 0;
  return Swig_name_make(n, 0, name, decl, 0);
}

// C version of add_symbols()
static void add_symbols_c(Node *n) {
  String *decl;
  String *wrn = 0;
  String *symname = 0;
  int iscdecl = Cmp(nodeType(n), "cdecl") == 0;
  Setattr(n, "ismember", "1");
  Setattr(n, "access", "public");
  if (Getattr(n, "sym:name"))
    return;
  decl = Getattr(n, "decl");
  if (!SwigType_isfunction(decl)) {
    String *name = Getattr(n, "name");
    String *makename = Getattr(n, "parser:makename");
    if (iscdecl) {
      String *storage = Getattr(n, "storage");
      if (Cmp(storage, "typedef") == 0) {
	Setattr(n, "kind", "typedef");
      } else {
	SwigType *type = Getattr(n, "type");
	String *value = Getattr(n, "value");
	Setattr(n, "kind", "variable");
	if (value && Len(value)) {
	  Setattr(n, "hasvalue", "1");
	}
	if (!type) {
	  Printf(stderr, "notype name %s\n", name);
	}
      }
    }
    Swig_features_get(Swig_cparse_features(), 0, name, 0, n);
    if (makename) {
      symname = make_name(n, makename, 0);
      Delattr(n, "parser:makename");	/* temporary information, don't leave it hanging around */
    } else {
      makename = name;
      symname = make_name(n, makename, 0);
    }

    if (!symname) {
      symname = Copy(Getattr(n, "unnamed"));
    }
    if (symname) {
      wrn = Swig_name_warning(n, 0, symname, 0);
    }
  } else {
    String *name = Getattr(n, "name");
    SwigType *fdecl = Copy(decl);
    SwigType *fun = SwigType_pop_function(fdecl);
    if (iscdecl) {
      Setattr(n, "kind", "function");
    }

    Swig_features_get(Swig_cparse_features(), 0, name, fun, n);

    symname = make_name(n, name, fun);
    wrn = Swig_name_warning(n, 0, symname, fun);

    Delete(fdecl);
    Delete(fun);

  }
  if (!symname)
    return;
  if (GetFlag(n, "feature:ignore")) {
    /* Only add to C symbol table and continue */
    Swig_symbol_add(0, n);
  } else if (strncmp(Char(symname), "$ignore", 7) == 0) {
    char *c = Char(symname) + 7;
    SetFlag(n, "feature:ignore");
    if (strlen(c)) {
      SWIG_WARN_NODE_BEGIN(n);
      Swig_warning(0, Getfile(n), Getline(n), "%s\n", c + 1);
      SWIG_WARN_NODE_END(n);
    }
    Swig_symbol_add(0, n);
  } else {
    Node *c;
    if ((wrn) && (Len(wrn))) {
      String *metaname = symname;
      if (!Getmeta(metaname, "already_warned")) {
	SWIG_WARN_NODE_BEGIN(n);
	Swig_warning(0, Getfile(n), Getline(n), "%s\n", wrn);
	SWIG_WARN_NODE_END(n);
	Setmeta(metaname, "already_warned", "1");
      }
    }
    c = Swig_symbol_add(symname, n);

    if (c != n) {
      /* symbol conflict attempting to add in the new symbol */
      if (Getattr(n, "sym:weak")) {
	Setattr(n, "sym:name", symname);
      } else {
	int inclass = 1;
	Swig_symbol_conflict_warn(n, c, symname, inclass);
      }
    }
  }
  Delete(symname);
}

/* Strips C-style and C++-style comments from string in-place. */
static void strip_comments(char *string) {
  int state = 0;
  /*
   * 0 - not in comment
   * 1 - in c-style comment
   * 2 - in c++-style comment
   * 3 - in string
   * 4 - after reading / not in comments
   * 5 - after reading * in c-style comments
   * 6 - after reading \ in strings
   */
  char *c = string;
  while (*c) {
    switch (state) {
    case 0:
      if (*c == '\"')
	state = 3;
      else if (*c == '/')
	state = 4;
      break;
    case 1:
      if (*c == '*')
	state = 5;
      *c = ' ';
      break;
    case 2:
      if (*c == '\n')
	state = 0;
      else
	*c = ' ';
      break;
    case 3:
      if (*c == '\"')
	state = 0;
      else if (*c == '\\')
	state = 6;
      break;
    case 4:
      if (*c == '/') {
	*(c - 1) = ' ';
	*c = ' ';
	state = 2;
      } else if (*c == '*') {
	*(c - 1) = ' ';
	*c = ' ';
	state = 1;
      } else
	state = 0;
      break;
    case 5:
      if (*c == '/')
	state = 0;
      else
	state = 1;
      *c = ' ';
      break;
    case 6:
      state = 3;
      break;
    }
    ++c;
  }
}

// Create a %insert with a typedef to make a new name visible to C
static Node *create_insert(Node *n, bool noTypedef = false) {
  // format a typedef
  String *ccode = Getattr(n, "code");
  Push(ccode, " ");
  if (noTypedef) {
    Push(ccode, Getattr(n, "name"));
    Push(ccode, " ");
    Push(ccode, Getattr(n, "kind"));
  } else {
    Push(ccode, Getattr(n, "kind"));
    Push(ccode, "typedef ");
    Append(ccode, " ");
    Append(ccode, Getattr(n, "tdname"));
  }
  Append(ccode, ";");

  /* Strip comments - further code may break in presence of comments. */
  strip_comments(Char(ccode));

  /* Make all SWIG created typedef structs/unions/classes unnamed else
     redefinition errors occur - nasty hack alert. */
  if (!noTypedef) {
    const char *types_array[3] = { "struct", "union", "class" };
    for (int i = 0; i < 3; i++) {
      char *code_ptr = Char(ccode);
      while (code_ptr) {
	/* Replace struct name (as in 'struct name {...}' ) with whitespace
	   name will be between struct and opening brace */

	code_ptr = strstr(code_ptr, types_array[i]);
	if (code_ptr) {
	  char *open_bracket_pos;
	  code_ptr += strlen(types_array[i]);
	  open_bracket_pos = strchr(code_ptr, '{');
	  if (open_bracket_pos) {
	    /* Make sure we don't have something like struct A a; */
	    char *semi_colon_pos = strchr(code_ptr, ';');
	    if (!(semi_colon_pos && (semi_colon_pos < open_bracket_pos)))
	      while (code_ptr < open_bracket_pos)
		*code_ptr++ = ' ';
	  }
	}
      }
    }
  }
  {
    /* Remove SWIG directive %constant which may be left in the SWIG created typedefs */
    char *code_ptr = Char(ccode);
    while (code_ptr) {
      code_ptr = strstr(code_ptr, "%constant");
      if (code_ptr) {
	char *directive_end_pos = strchr(code_ptr, ';');
	if (directive_end_pos) {
	  while (code_ptr <= directive_end_pos)
	    *code_ptr++ = ' ';
	}
      }
    }
  }
  Node *newnode = NewHash();
  set_nodeType(newnode, "insert");
  Setfile(newnode, Getfile(n));
  Setline(newnode, Getline(n));
  String *code = NewStringEmpty();
  Wrapper_pretty_print(ccode, code);
  Setattr(newnode, "code", code);
  Delete(code);
  Delattr(n, "code");
  return newnode;
}

static void insertNodeAfter(Node *n, Node *c) {
  Node *g = parentNode(n);
  set_parentNode(c, g);
  Node *ns = nextSibling(n);
  if (Node *outer = Getattr(c, "nested:outer")) {
    while (ns && outer == Getattr(ns, "nested:outer")) {
      n = ns;
      ns = nextSibling(n);
    }
  }
  if (!ns) {
    set_lastChild(g, c);
  } else {
    set_nextSibling(c, ns);
    set_previousSibling(ns, c);
  }
  set_nextSibling(n, c);
  set_previousSibling(c, n);
}

void Swig_nested_name_unnamed_c_structs(Node *n) {
  if (!n)
    return;
  if (!classhash)
    classhash = Getattr(n, "classes");
  Node *c = firstChild(n);
  while (c) {
    Node *next = nextSibling(c);
    if (String *declName = Getattr(c, "nested:unnamed")) {
      if (Node *outer = Getattr(c, "nested:outer")) {
	// generate a name
	String *name = NewStringf("%s_%s", Getattr(outer, "name"), declName);
	Delattr(c, "nested:unnamed");
	// set the name to the class and symbol table
	Setattr(c, "tdname", name);
	Setattr(c, "name", name);
	Swig_symbol_setscope(Getattr(c, "symtab"));
	Swig_symbol_setscopename(name);
	// now that we have a name - gather base symbols
	if (List *publicBases = Getattr(c, "baselist")) {
	  List *bases = Swig_make_inherit_list(name, publicBases, 0);
	  Swig_inherit_base_symbols(bases);
	  Delete(bases);
	}
	Setattr(classhash, name, c);

	// Merge the extension into the symbol table
	if (Node *am = Getattr(Swig_extend_hash(), name)) {
	  Swig_extend_merge(c, am);
	  Swig_extend_append_previous(c, am);
	  Delattr(Swig_extend_hash(), name);
	}
	Swig_symbol_popscope();

	// process declarations following this type (assign correct new type)
	SwigType *ty = Copy(name);
	Node *decl = nextSibling(c);
	List *declList = NewList();
	while (decl && Getattr(decl, "nested:unnamedtype") == c) {
	  Setattr(decl, "type", ty);
	  Append(declList, decl);
	  Delattr(decl, "nested:unnamedtype");
	  SetFlag(decl, "feature:immutable");
	  add_symbols_c(decl);
	  decl = nextSibling(decl);
	}
	Delete(ty);
	Swig_symbol_setscope(Swig_symbol_global_scope());
	add_symbols_c(c);

	Node *ins = create_insert(c);
	insertNodeAfter(c, ins);
	removeNode(c);
	insertNodeAfter(n, c);
	Delete(ins);
	Delattr(c, "nested:outer");
      } else {
	// global unnamed struct - ignore it and its instances
	SetFlag(c, "feature:ignore");
	while (next && Getattr(next, "nested:unnamedtype") == c) {
	  SetFlag(next, "feature:ignore");
	  next = nextSibling(next);
	}
	c = next;
	continue;
      }
    } else if (cparse_cplusplusout) {
      if (Getattr(c, "nested:outer")) {
	Node *ins = create_insert(c, true);
	insertNodeAfter(c, ins);
	Delete(ins);
	Delattr(c, "nested:outer");
      }
    }
    // process children
    Swig_nested_name_unnamed_c_structs(c);
    c = next;
  }
}

static void remove_outer_class_reference(Node *n) {
  for (Node *c = firstChild(n); c; c = nextSibling(c)) {
    if (GetFlag(c, "feature:flatnested") || Language::instance()->nestedClassesSupport() == Language::NCS_None) {
      Delattr(c, "nested:outer");
      remove_outer_class_reference(c);
    }
  }
}

void Swig_nested_process_classes(Node *n) {
  if (!n)
    return;
  Node *c = firstChild(n);
  while (c) {
    Node *next = nextSibling(c);
    if (!Getattr(c, "templatetype")) {
      if (GetFlag(c, "nested") && (GetFlag(c, "feature:flatnested") || Language::instance()->nestedClassesSupport() == Language::NCS_None)) {
	removeNode(c);
	if (!checkAttribute(c, "access", "public"))
	  SetFlag(c, "feature:ignore");
	else if (Strcmp(nodeType(n),"extend") == 0 && Strcmp(nodeType(parentNode(n)),"class") == 0)
	  insertNodeAfter(parentNode(n), c);
	else
	  insertNodeAfter(n, c);
      }
      Swig_nested_process_classes(c);
    }
    c = next;
  }
  remove_outer_class_reference(n);
}

