//========================================================================
//
// 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, 2019 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>
// Copyright (C) 2018 Adam Reichold <adam.reichold@t-online.de>
//
// 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>

#include <algorithm>

#include "XRef.h"
#include "Dict.h"

//------------------------------------------------------------------------
// Dict
//------------------------------------------------------------------------

#define dictLocker()   std::unique_lock<std::recursive_mutex> locker(mutex)

constexpr int SORT_LENGTH_LOWER_LIMIT = 32;

struct Dict::CmpDictEntry {
  bool operator()(const DictEntry &lhs, const DictEntry &rhs) const {
    return lhs.first < rhs.first;
  }
  bool operator()(const DictEntry &lhs, const char *rhs) const {
    return lhs.first < rhs;
  }
  bool operator()(const char *lhs, const DictEntry &rhs) const {
    return lhs < rhs.first;
  }
};

Dict::Dict(XRef *xrefA) {
  xref = xrefA;
  ref = 1;

  sorted = false;
}

Dict::Dict(const Dict* dictA) {
  xref = dictA->xref;
  ref = 1;

  entries.reserve(dictA->entries.size());
  for (const auto& entry : dictA->entries) {
    entries.emplace_back(entry.first, entry.second.copy());
  }

  sorted = dictA->sorted.load();
}

Dict *Dict::copy(XRef *xrefA) const {
  dictLocker();
  Dict *dictA = new Dict(this);
  dictA->xref = xrefA;
  for (auto &entry : dictA->entries) {
    if (entry.second.getType() == objDict) {
      entry.second = Object(entry.second.getDict()->copy(xrefA));
    }
  }
  return dictA;
}

void Dict::add(const char *key, Object &&val) {
  dictLocker();
  entries.emplace_back(key, std::move(val));
  sorted = false;
}

inline const Dict::DictEntry *Dict::find(const char *key) const {
  if (entries.size() >= SORT_LENGTH_LOWER_LIMIT) {
    if (!sorted) {
      dictLocker();
      if (!sorted) {
	Dict *that = const_cast<Dict*>(this);

	std::sort(that->entries.begin(), that->entries.end(), CmpDictEntry{});
	that->sorted = true;
      }
    }
  }

  if (sorted) {
    const auto pos = std::lower_bound(entries.begin(), entries.end(), key, CmpDictEntry{});
    if (pos != entries.end() && pos->first == key) {
      return &*pos;
    }
  } else {
    const auto pos = std::find_if(entries.rbegin(), entries.rend(), [key](const DictEntry& entry) {
      return entry.first == key;
    });
    if (pos != entries.rend()) {
      return &*pos;
    }
  }
  return nullptr;
}

inline Dict::DictEntry *Dict::find(const char *key) {
  return const_cast<DictEntry *>(const_cast<const Dict *>(this)->find(key));
}

void Dict::remove(const char *key) {
  dictLocker();
  if (auto *entry = find(key)) {
    if (sorted) {
      const auto index = entry - &entries.front();
      entries.erase(entries.begin() + index);
    } else {
      swap(*entry, entries.back());
      entries.pop_back();
    }
  }
}

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


bool Dict::is(const char *type) const {
  if (const auto *entry = find("Type")) {
    return entry->second.isName(type);
  }
  return false;
}

Object Dict::lookup(const char *key, int recursion) const {
  if (const auto *entry = find(key)) {
    return entry->second.fetch(xref, recursion);
  }
  return Object(objNull);
}

Object Dict::lookup(const char *key, Ref *returnRef, int recursion) const {
  if (const auto *entry = find(key)) {
    if (entry->second.getType() == objRef) {
      *returnRef = entry->second.getRef();
    } else {
      *returnRef = Ref::INVALID();
    }
    return entry->second.fetch(xref, recursion);
  }
  *returnRef = Ref::INVALID();
  return Object(objNull);
}

const Object &Dict::lookupNF(const char *key) const {
  if (const auto *entry = find(key)) {
    return entry->second;
  }
  static Object nullObj(objNull);
  return nullObj;
}

bool Dict::lookupInt(const char *key, const char *alt_key, int *value) const
{
  auto obj1 = lookup(key);
  if (obj1.isNull() && alt_key != nullptr) {
    obj1 = lookup(alt_key);
  }
  if (obj1.isInt()) {
    *value = obj1.getInt();
    return true;
  }
  return false;
}

Object Dict::getVal(int i, Ref *returnRef) const
{
    const DictEntry &entry = entries[i];
    if (entry.second.getType() == objRef) {
      *returnRef = entry.second.getRef();
    } else {
      *returnRef = Ref::INVALID();
    }
    return entry.second.fetch(xref);
}

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