//========================================================================
//
// Dict.cc
//
// Copyright 1996-2003 Glyph & Cog, LLC
//
//========================================================================

//========================================================================
//
// Modified under the Poppler project - http://poppler.freedesktop.org
//
// All changes made under the Poppler project to this file are licensed
// under GPL version 2 or later
//
// Copyright (C) 2005 Kristian Høgsberg <krh@redhat.com>
// Copyright (C) 2006 Krzysztof Kowalczyk <kkowalczyk@gmail.com>
// Copyright (C) 2007-2008 Julien Rebetez <julienr@svn.gnome.org>
// Copyright (C) 2008, 2010, 2013, 2014, 2017 Albert Astals Cid <aacid@kde.org>
// Copyright (C) 2010 Paweł Wiejacha <pawel.wiejacha@gmail.com>
// Copyright (C) 2012 Fabio D'Urso <fabiodurso@hotmail.it>
// Copyright (C) 2013 Thomas Freitag <Thomas.Freitag@alfa.de>
// Copyright (C) 2014 Scott West <scott.gregory.west@gmail.com>
// Copyright (C) 2017 Adrian Johnson <ajohnson@redneon.com>
//
// To see a description of the changes please see the Changelog file that
// came with your tarball or type make ChangeLog if you are building from git
//
//========================================================================

#include <config.h>

#ifdef USE_GCC_PRAGMAS
#pragma implementation
#endif

#include <algorithm>
#include <stddef.h>
#include <string.h>
#include "goo/gmem.h"
#include "Object.h"
#include "XRef.h"
#include "Dict.h"

#ifdef MULTITHREADED
#  define dictLocker()   MutexLocker locker(&mutex)
#else
#  define dictLocker()
#endif
//------------------------------------------------------------------------
// Dict
//------------------------------------------------------------------------

static const int SORT_LENGTH_LOWER_LIMIT = 32;

static inline bool cmpDictEntries(const DictEntry &e1, const DictEntry &e2)
{
  return strcmp(e1.key, e2.key) < 0;
}

static int binarySearch(const char *key, DictEntry *entries, int length)
{
  int first = 0;
  int end = length - 1;
  while (first <= end) {
    const int middle = (first + end) / 2;
    const int res = strcmp(key, entries[middle].key);
    if (res == 0) {
      return middle;
    } else if (res < 0) {
      end = middle - 1;
    } else {
      first = middle + 1;
    }
  }
  return -1;
}

Dict::Dict(XRef *xrefA) {
  xref = xrefA;
  entries = NULL;
  size = length = 0;
  ref = 1;
  sorted = gFalse;
#ifdef MULTITHREADED
  gInitMutex(&mutex);
#endif
}

Dict::Dict(Dict* dictA) {
  xref = dictA->xref;
  size = length = dictA->length;
  ref = 1;
#ifdef MULTITHREADED
  gInitMutex(&mutex);
#endif

  sorted = dictA->sorted;
  entries = (DictEntry *)gmallocn(size, sizeof(DictEntry));
  for (int i=0; i<length; i++) {
    entries[i].key = copyString(dictA->entries[i].key);
    entries[i].val.initNullAfterMalloc();
    entries[i].val = dictA->entries[i].val.copy();
  }
}

Dict *Dict::copy(XRef *xrefA) {
  dictLocker();
  Dict *dictA = new Dict(this);
  dictA->xref = xrefA;
  for (int i=0; i<length; i++) {
    if (dictA->entries[i].val.getType() == objDict) {
       Dict *copy = dictA->entries[i].val.getDict()->copy(xrefA);
       dictA->entries[i].val = Object(copy);
    }
  }
  return dictA;
}

Dict::~Dict() {
  int i;

  for (i = 0; i < length; ++i) {
    gfree(entries[i].key);
    entries[i].val.free();
  }
  gfree(entries);
#ifdef MULTITHREADED
  gDestroyMutex(&mutex);
#endif
}

int Dict::incRef() {
  dictLocker();
  ++ref;
  return ref;
}

int Dict::decRef() {
  dictLocker();
  --ref;
  return ref;
}

void Dict::add(char *key, Object &&val) {
  dictLocker();
  if (sorted) {
    // We use add on very few occasions so
    // virtually this will never be hit
    sorted = gFalse;
  }

  if (length == size) {
    if (length == 0) {
      size = 8;
    } else {
      size *= 2;
    }
    entries = (DictEntry *)greallocn(entries, size, sizeof(DictEntry));
  }
  entries[length].key = key;
  entries[length].val.initNullAfterMalloc();
  entries[length].val = std::move(val);
  ++length;
}

inline DictEntry *Dict::find(const char *key) const {
  if (!sorted && length >= SORT_LENGTH_LOWER_LIMIT)
  {
      dictLocker();
      sorted = gTrue;
      std::sort(entries, entries+length, cmpDictEntries);
  }

  if (sorted) {
    const int pos = binarySearch(key, entries, length);
    if (pos != -1) {
      return &entries[pos];
    }
  } else {
    int i;

    for (i = length - 1; i >=0; --i) {
      if (!strcmp(key, entries[i].key))
        return &entries[i];
    }
  }
  return NULL;
}

GBool Dict::hasKey(const char *key) const {
  return find(key) != NULL;
}

void Dict::remove(const char *key) {
  dictLocker();
  if (sorted) {
    const int pos = binarySearch(key, entries, length);
    if (pos != -1) {
      length -= 1;
      gfree(entries[pos].key);
      entries[pos].val.free();
      if (pos != length) {
        memmove(&entries[pos], &entries[pos + 1], (length - pos) * sizeof(DictEntry));
      }
    }
  } else {
    int i; 
    bool found = false;
    if(length == 0) {
      return;
    }

    for(i=0; i<length; i++) {
      if (!strcmp(key, entries[i].key)) {
        found = true;
        break;
      }
    }
    if(!found) {
      return;
    }
    //replace the deleted entry with the last entry
    gfree(entries[i].key);
    entries[i].val.free();
    length -= 1;
    if (i!=length) {
      //don't copy the last entry if it is deleted
      entries[i].key = entries[length].key;
      entries[i].val = std::move(entries[length].val);
    }
  }
}

void Dict::set(const char *key, Object &&val) {
  DictEntry *e;
  if (val.isNull()) {
    remove(key);
    return;
  }
  e = find (key);
  if (e) {
    dictLocker();
    e->val = std::move(val);
  } else {
    add (copyString(key), std::move(val));
  }
}


GBool Dict::is(const char *type) const {
  DictEntry *e;

  return (e = find("Type")) && e->val.isName(type);
}

Object Dict::lookup(const char *key, int recursion) const {
  DictEntry *e;

  return (e = find(key)) ? e->val.fetch(xref, recursion) : Object(objNull);
}

Object Dict::lookupNF(const char *key) const {
  DictEntry *e;

  return (e = find(key)) ? e->val.copy() : Object(objNull);
}

GBool Dict::lookupInt(const char *key, const char *alt_key, int *value) const
{
  GBool success = gFalse;
  Object obj1 = lookup ((char *) key);
  if (obj1.isNull () && alt_key != NULL) {
    obj1.free ();
    obj1 = lookup ((char *) alt_key);
  }
  if (obj1.isInt ()) {
    *value = obj1.getInt ();
    success = gTrue;
  }

  obj1.free ();

  return success;
}

char *Dict::getKey(int i) const {
  return entries[i].key;
}

Object Dict::getVal(int i) const {
  return entries[i].val.fetch(xref);
}

Object Dict::getValNF(int i) const {
  return entries[i].val.copy();
}
