// Copyright (c) 2019 Pantor. All rights reserved.

#ifndef INCLUDE_INJA_RENDERER_HPP_
#define INCLUDE_INJA_RENDERER_HPP_

#include <algorithm>
#include <numeric>
#include <string>
#include <utility>
#include <vector>

#include <nlohmann/json.hpp>

#include "config.hpp"
#include "exceptions.hpp"
#include "node.hpp"
#include "template.hpp"
#include "utils.hpp"

namespace inja {

inline nonstd::string_view convert_dot_to_json_pointer(nonstd::string_view dot, std::string &out) {
  out.clear();
  do {
    nonstd::string_view part;
    std::tie(part, dot) = string_view::split(dot, '.');
    out.push_back('/');
    out.append(part.begin(), part.end());
  } while (!dot.empty());
  return nonstd::string_view(out.data(), out.size());
}

/*!
 * \brief Class for rendering a Template with data.
 */
class Renderer {
  std::vector<const json *> &get_args(const Node &node) {
    m_tmp_args.clear();

    bool has_imm = ((node.flags & Node::Flag::ValueMask) != Node::Flag::ValuePop);

    // get args from stack
    unsigned int pop_args = node.args;
    if (has_imm) {
      pop_args -= 1;
    }

    for (auto i = std::prev(m_stack.end(), pop_args); i != m_stack.end(); i++) {
      m_tmp_args.push_back(&(*i));
    }

    // get immediate arg
    if (has_imm) {
      m_tmp_args.push_back(get_imm(node));
    }

    return m_tmp_args;
  }

  void pop_args(const Node &node) {
    unsigned int pop_args = node.args;
    if ((node.flags & Node::Flag::ValueMask) != Node::Flag::ValuePop) {
      pop_args -= 1;
    }
    for (unsigned int i = 0; i < pop_args; ++i) {
      m_stack.pop_back();
    }
  }

  const json *get_imm(const Node &node) {
    std::string ptr_buffer;
    nonstd::string_view ptr;
    switch (node.flags & Node::Flag::ValueMask) {
    case Node::Flag::ValuePop:
      return nullptr;
    case Node::Flag::ValueImmediate:
      return &node.value;
    case Node::Flag::ValueLookupDot:
      ptr = convert_dot_to_json_pointer(node.str, ptr_buffer);
      break;
    case Node::Flag::ValueLookupPointer:
      ptr_buffer += '/';
      ptr_buffer += node.str;
      ptr = ptr_buffer;
      break;
    }
    
    json::json_pointer json_ptr(ptr.data());
    try {
      // first try to evaluate as a loop variable
      // Using contains() is faster than unsucessful at() and throwing an exception
      if (m_loop_data && m_loop_data->contains(json_ptr)) {
        return &m_loop_data->at(json_ptr);
      }
      return &m_data->at(json_ptr);
    } catch (std::exception &) {
      // try to evaluate as a no-argument callback
      if (auto callback = function_storage.find_callback(node.str, 0)) {
        std::vector<const json *> arguments {};
        m_tmp_val = callback(arguments);
        return &m_tmp_val;
      }

      throw_renderer_error("variable '" + static_cast<std::string>(node.str) + "' not found", node);
      return nullptr;
    }
  }

  bool truthy(const json &var) const {
    if (var.empty()) {
      return false;
    } else if (var.is_number()) {
      return (var != 0);
    } else if (var.is_string()) {
      return !var.empty();
    }

    try {
      return var.get<bool>();
    } catch (json::type_error &e) {
      throw JsonError(e.what());
    }
  }

  void update_loop_data() {
    LoopLevel &level = m_loop_stack.back();

    if (level.loop_type == LoopLevel::Type::Array) {
      level.data[static_cast<std::string>(level.value_name)] = level.values.at(level.index); // *level.it;
    } else {
      level.data[static_cast<std::string>(level.key_name)] = level.map_it->first;
      level.data[static_cast<std::string>(level.value_name)] = *level.map_it->second;
    }
    auto &loop_data = level.data["loop"];
    loop_data["index"] = level.index;
    loop_data["index1"] = level.index + 1;
    loop_data["is_first"] = (level.index == 0);
    loop_data["is_last"] = (level.index == level.size - 1);
  }

  void throw_renderer_error(const std::string &message, const Node& node) {
    SourceLocation loc = get_source_location(current_template->content, node.pos);
    throw RenderError(message, loc);
  }

  struct LoopLevel {
    enum class Type { Map, Array };

    Type loop_type;
    nonstd::string_view key_name;   // variable name for keys
    nonstd::string_view value_name; // variable name for values
    json data;                      // data with loop info added

    json values; // values to iterate over

    // loop over list
    size_t index; // current list index
    size_t size;  // length of list

    // loop over map
    using KeyValue = std::pair<nonstd::string_view, json *>;
    using MapValues = std::vector<KeyValue>;
    MapValues map_values;       // values to iterate over
    MapValues::iterator map_it; // iterator over values
  };

  const TemplateStorage &template_storage;
  const FunctionStorage &function_storage;

  const Template *current_template;
  std::vector<json> m_stack;
  std::vector<LoopLevel> m_loop_stack;
  json *m_loop_data;

  const json *m_data;
  std::vector<const json *> m_tmp_args;
  json m_tmp_val;

  RenderConfig config;

public:
  Renderer(const RenderConfig& config, const TemplateStorage &included_templates, const FunctionStorage &callbacks)
      : config(config), template_storage(included_templates), function_storage(callbacks) {
    m_stack.reserve(16);
    m_tmp_args.reserve(4);
    m_loop_stack.reserve(16);
  }

  void render_to(std::ostream &os, const Template &tmpl, const json &data, json *loop_data = nullptr) {
    current_template = &tmpl;
    m_data = &data;
    m_loop_data = loop_data;

    for (size_t i = 0; i < tmpl.nodes.size(); ++i) {
      const auto &node = tmpl.nodes[i];

      switch (node.op) {
      case Node::Op::Nop: {
        break;
      }
      case Node::Op::PrintText: {
        os << node.str;
        break;
      }
      case Node::Op::PrintValue: {
        const json &val = *get_args(node)[0];
        if (val.is_string()) {
          os << val.get_ref<const std::string &>();
        } else {
          os << val.dump();
        }
        pop_args(node);
        break;
      }
      case Node::Op::Push: {
        m_stack.emplace_back(*get_imm(node));
        break;
      }
      case Node::Op::Upper: {
        auto result = get_args(node)[0]->get<std::string>();
        std::transform(result.begin(), result.end(), result.begin(), ::toupper);
        pop_args(node);
        m_stack.emplace_back(std::move(result));
        break;
      }
      case Node::Op::Lower: {
        auto result = get_args(node)[0]->get<std::string>();
        std::transform(result.begin(), result.end(), result.begin(), ::tolower);
        pop_args(node);
        m_stack.emplace_back(std::move(result));
        break;
      }
      case Node::Op::Range: {
        int number = get_args(node)[0]->get<int>();
        std::vector<int> result(number);
        std::iota(std::begin(result), std::end(result), 0);
        pop_args(node);
        m_stack.emplace_back(std::move(result));
        break;
      }
      case Node::Op::Length: {
        const json &val = *get_args(node)[0];

        size_t result;
        if (val.is_string()) {
          result = val.get_ref<const std::string &>().length();
        } else {
          result = val.size();
        }

        pop_args(node);
        m_stack.emplace_back(result);
        break;
      }
      case Node::Op::Sort: {
        auto result = get_args(node)[0]->get<std::vector<json>>();
        std::sort(result.begin(), result.end());
        pop_args(node);
        m_stack.emplace_back(std::move(result));
        break;
      }
      case Node::Op::At: {
        auto args = get_args(node);
        auto result = args[0]->at(args[1]->get<int>());
        pop_args(node);
        m_stack.emplace_back(result);
        break;
      }
      case Node::Op::First: {
        auto result = get_args(node)[0]->front();
        pop_args(node);
        m_stack.emplace_back(result);
        break;
      }
      case Node::Op::Last: {
        auto result = get_args(node)[0]->back();
        pop_args(node);
        m_stack.emplace_back(result);
        break;
      }
      case Node::Op::Round: {
        auto args = get_args(node);
        double number = args[0]->get<double>();
        int precision = args[1]->get<int>();
        pop_args(node);
        m_stack.emplace_back(std::round(number * std::pow(10.0, precision)) / std::pow(10.0, precision));
        break;
      }
      case Node::Op::DivisibleBy: {
        auto args = get_args(node);
        int number = args[0]->get<int>();
        int divisor = args[1]->get<int>();
        pop_args(node);
        m_stack.emplace_back((divisor != 0) && (number % divisor == 0));
        break;
      }
      case Node::Op::Odd: {
        int number = get_args(node)[0]->get<int>();
        pop_args(node);
        m_stack.emplace_back(number % 2 != 0);
        break;
      }
      case Node::Op::Even: {
        int number = get_args(node)[0]->get<int>();
        pop_args(node);
        m_stack.emplace_back(number % 2 == 0);
        break;
      }
      case Node::Op::Max: {
        auto args = get_args(node);
        auto result = *std::max_element(args[0]->begin(), args[0]->end());
        pop_args(node);
        m_stack.emplace_back(std::move(result));
        break;
      }
      case Node::Op::Min: {
        auto args = get_args(node);
        auto result = *std::min_element(args[0]->begin(), args[0]->end());
        pop_args(node);
        m_stack.emplace_back(std::move(result));
        break;
      }
      case Node::Op::Not: {
        bool result = !truthy(*get_args(node)[0]);
        pop_args(node);
        m_stack.emplace_back(result);
        break;
      }
      case Node::Op::And: {
        auto args = get_args(node);
        bool result = truthy(*args[0]) && truthy(*args[1]);
        pop_args(node);
        m_stack.emplace_back(result);
        break;
      }
      case Node::Op::Or: {
        auto args = get_args(node);
        bool result = truthy(*args[0]) || truthy(*args[1]);
        pop_args(node);
        m_stack.emplace_back(result);
        break;
      }
      case Node::Op::In: {
        auto args = get_args(node);
        bool result = std::find(args[1]->begin(), args[1]->end(), *args[0]) != args[1]->end();
        pop_args(node);
        m_stack.emplace_back(result);
        break;
      }
      case Node::Op::Equal: {
        auto args = get_args(node);
        bool result = (*args[0] == *args[1]);
        pop_args(node);
        m_stack.emplace_back(result);
        break;
      }
      case Node::Op::Greater: {
        auto args = get_args(node);
        bool result = (*args[0] > *args[1]);
        pop_args(node);
        m_stack.emplace_back(result);
        break;
      }
      case Node::Op::Less: {
        auto args = get_args(node);
        bool result = (*args[0] < *args[1]);
        pop_args(node);
        m_stack.emplace_back(result);
        break;
      }
      case Node::Op::GreaterEqual: {
        auto args = get_args(node);
        bool result = (*args[0] >= *args[1]);
        pop_args(node);
        m_stack.emplace_back(result);
        break;
      }
      case Node::Op::LessEqual: {
        auto args = get_args(node);
        bool result = (*args[0] <= *args[1]);
        pop_args(node);
        m_stack.emplace_back(result);
        break;
      }
      case Node::Op::Different: {
        auto args = get_args(node);
        bool result = (*args[0] != *args[1]);
        pop_args(node);
        m_stack.emplace_back(result);
        break;
      }
      case Node::Op::Float: {
        double result = std::stod(get_args(node)[0]->get_ref<const std::string &>());
        pop_args(node);
        m_stack.emplace_back(result);
        break;
      }
      case Node::Op::Int: {
        int result = std::stoi(get_args(node)[0]->get_ref<const std::string &>());
        pop_args(node);
        m_stack.emplace_back(result);
        break;
      }
      case Node::Op::Exists: {
        auto &&name = get_args(node)[0]->get_ref<const std::string &>();
        bool result = (data.find(name) != data.end());
        pop_args(node);
        m_stack.emplace_back(result);
        break;
      }
      case Node::Op::ExistsInObject: {
        auto args = get_args(node);
        auto &&name = args[1]->get_ref<const std::string &>();
        bool result = (args[0]->find(name) != args[0]->end());
        pop_args(node);
        m_stack.emplace_back(result);
        break;
      }
      case Node::Op::IsBoolean: {
        bool result = get_args(node)[0]->is_boolean();
        pop_args(node);
        m_stack.emplace_back(result);
        break;
      }
      case Node::Op::IsNumber: {
        bool result = get_args(node)[0]->is_number();
        pop_args(node);
        m_stack.emplace_back(result);
        break;
      }
      case Node::Op::IsInteger: {
        bool result = get_args(node)[0]->is_number_integer();
        pop_args(node);
        m_stack.emplace_back(result);
        break;
      }
      case Node::Op::IsFloat: {
        bool result = get_args(node)[0]->is_number_float();
        pop_args(node);
        m_stack.emplace_back(result);
        break;
      }
      case Node::Op::IsObject: {
        bool result = get_args(node)[0]->is_object();
        pop_args(node);
        m_stack.emplace_back(result);
        break;
      }
      case Node::Op::IsArray: {
        bool result = get_args(node)[0]->is_array();
        pop_args(node);
        m_stack.emplace_back(result);
        break;
      }
      case Node::Op::IsString: {
        bool result = get_args(node)[0]->is_string();
        pop_args(node);
        m_stack.emplace_back(result);
        break;
      }
      case Node::Op::Default: {
        // default needs to be a bit "magic"; we can't evaluate the first
        // argument during the push operation, so we swap the arguments during
        // the parse phase so the second argument is pushed on the stack and
        // the first argument is in the immediate
        try {
          const json *imm = get_imm(node);
          // if no exception was raised, replace the stack value with it
          m_stack.back() = *imm;
        } catch (std::exception &) {
          // couldn't read immediate, just leave the stack as is
        }
        break;
      }
      case Node::Op::Include: {
        auto sub_renderer = Renderer(config, template_storage, function_storage);
        auto include_name = get_imm(node)->get_ref<const std::string &>();
        auto included_template_it = template_storage.find(include_name);
        if (included_template_it != template_storage.end()) {
          sub_renderer.render_to(os, included_template_it->second, *m_data, m_loop_data);
        } else if (config.throw_at_missing_includes) {
          throw_renderer_error("include '" + include_name + "' not found", node);
        }
        break;
      }
      case Node::Op::Callback: {
        auto callback = function_storage.find_callback(node.str, node.args);
        if (!callback) {
          throw_renderer_error("function '" + static_cast<std::string>(node.str) + "' (" +
                            std::to_string(static_cast<unsigned int>(node.args)) + ") not found", node);
        }
        json result = callback(get_args(node));
        pop_args(node);
        m_stack.emplace_back(std::move(result));
        break;
      }
      case Node::Op::Jump: {
        i = node.args - 1; // -1 due to ++i in loop
        break;
      }
      case Node::Op::ConditionalJump: {
        if (!truthy(m_stack.back())) {
          i = node.args - 1; // -1 due to ++i in loop
        }
        m_stack.pop_back();
        break;
      }
      case Node::Op::StartLoop: {
        // jump past loop body if empty
        if (m_stack.back().empty()) {
          m_stack.pop_back();
          i = node.args; // ++i in loop will take it past EndLoop
          break;
        }

        m_loop_stack.emplace_back();
        LoopLevel &level = m_loop_stack.back();
        level.value_name = node.str;
        level.values = std::move(m_stack.back());
        if (m_loop_data) {
          level.data = *m_loop_data;
        }
        level.index = 0;
        m_stack.pop_back();

        if (node.value.is_string()) {
          // map iterator
          if (!level.values.is_object()) {
            m_loop_stack.pop_back();
            throw_renderer_error("for key, value requires object", node);
          }
          level.loop_type = LoopLevel::Type::Map;
          level.key_name = node.value.get_ref<const std::string &>();

          // sort by key
          for (auto it = level.values.begin(), end = level.values.end(); it != end; ++it) {
            level.map_values.emplace_back(it.key(), &it.value());
          }
          auto sort_lambda = [](const LoopLevel::KeyValue &a, const LoopLevel::KeyValue &b) {
            return a.first < b.first;
          };
          std::sort(level.map_values.begin(), level.map_values.end(), sort_lambda);
          level.map_it = level.map_values.begin();
          level.size = level.map_values.size();
        } else {
          if (!level.values.is_array()) {
            m_loop_stack.pop_back();
            throw_renderer_error("type must be array", node);
          }

          // list iterator
          level.loop_type = LoopLevel::Type::Array;
          level.size = level.values.size();
        }

        // provide parent access in nested loop
        auto parent_loop_it = level.data.find("loop");
        if (parent_loop_it != level.data.end()) {
          json loop_copy = *parent_loop_it;
          (*parent_loop_it)["parent"] = std::move(loop_copy);
        }

        // set "current" loop data to this level
        m_loop_data = &level.data;
        update_loop_data();
        break;
      }
      case Node::Op::EndLoop: {
        if (m_loop_stack.empty()) {
          throw_renderer_error("unexpected state in renderer", node);
        }
        LoopLevel &level = m_loop_stack.back();

        bool done;
        level.index += 1;
        if (level.loop_type == LoopLevel::Type::Array) {
          done = (level.index == level.values.size());
        } else {
          level.map_it += 1;
          done = (level.map_it == level.map_values.end());
        }

        if (done) {
          m_loop_stack.pop_back();
          // set "current" data to outer loop data or main data as appropriate
          if (!m_loop_stack.empty()) {
            m_loop_data = &m_loop_stack.back().data;
          } else {
            m_loop_data = loop_data;
          }
          break;
        }

        update_loop_data();

        // jump back to start of loop
        i = node.args - 1; // -1 due to ++i in loop
        break;
      }
      default: {
        throw_renderer_error("unknown operation in renderer: " + std::to_string(static_cast<unsigned int>(node.op)), node);
      }
      }
    }
  }
};

} // namespace inja

#endif // INCLUDE_INJA_RENDERER_HPP_
