/*
 * Copyright 2015 WebAssembly Community Group participants
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "simple_ast.h"

namespace cashew {

// Ref methods

Ref& Ref::operator[](unsigned x) { return (*get())[x]; }

Ref& Ref::operator[](IString x) { return (*get())[x]; }

bool Ref::operator==(const char* str) {
  return get()->isString() && !strcmp(get()->str.str, str);
}

bool Ref::operator!=(const char* str) {
  return get()->isString() ? !!strcmp(get()->str.str, str) : true;
}

bool Ref::operator==(const IString& str) {
  return get()->isString() && get()->str == str;
}

bool Ref::operator!=(const IString& str) {
  return get()->isString() && get()->str != str;
}

bool Ref::operator==(Ref other) { return **this == *other; }

bool Ref::operator!() { return !get() || get()->isNull(); }

// Arena

GlobalMixedArena arena;

// Value

Value& Value::setAssign(Ref target, Ref value) {
  asAssign()->target() = target;
  asAssign()->value() = value;
  return *this;
}

Value& Value::setAssignName(IString target, Ref value) {
  asAssignName()->target() = target;
  asAssignName()->value() = value;
  return *this;
}

Assign* Value::asAssign() {
  assert(isAssign());
  return static_cast<Assign*>(this);
}

AssignName* Value::asAssignName() {
  assert(isAssignName());
  return static_cast<AssignName*>(this);
}

void Value::stringify(std::ostream& os, bool pretty) {
  static int indent = 0;
#define indentify()                                                            \
  {                                                                            \
    for (int i_ = 0; i_ < indent; i_++)                                        \
      os << "  ";                                                              \
  }
  switch (type) {
    case String: {
      if (str.str) {
        os << '"' << str.str << '"';
      } else {
        os << "\"(null)\"";
      }
      break;
    }
    case Number: {
      // doubles can have 17 digits of precision
      os << std::setprecision(17) << num;
      break;
    }
    case Array: {
      if (arr->size() == 0) {
        os << "[]";
        break;
      }
      os << '[';
      if (pretty) {
        os << std::endl;
        indent++;
      }
      for (size_t i = 0; i < arr->size(); i++) {
        if (i > 0) {
          if (pretty) {
            os << "," << std::endl;
          } else {
            os << ", ";
          }
        }
        indentify();
        (*arr)[i]->stringify(os, pretty);
      }
      if (pretty) {
        os << std::endl;
        indent--;
      }
      indentify();
      os << ']';
      break;
    }
    case Null: {
      os << "null";
      break;
    }
    case Bool: {
      os << (boo ? "true" : "false");
      break;
    }
    case Object: {
      os << '{';
      if (pretty) {
        os << std::endl;
        indent++;
      }
      bool first = true;
      for (auto i : *obj) {
        if (first) {
          first = false;
        } else {
          os << ", ";
          if (pretty) {
            os << std::endl;
          }
        }
        indentify();
        os << '"' << i.first.c_str() << "\": ";
        i.second->stringify(os, pretty);
      }
      if (pretty) {
        os << std::endl;
        indent--;
      }
      indentify();
      os << '}';
      break;
    }
    case Assign_: {
      os << "[";
      ref->stringify(os, pretty);
      os << ", ";
      asAssign()->value()->stringify(os, pretty);
      os << "]";
      break;
    }
    case AssignName_: {
      os << "[\"" << asAssignName()->target().str << "\"";
      os << ", ";
      asAssignName()->value()->stringify(os, pretty);
      os << "]";
      break;
    }
  }
}

// dump

void dump(const char* str, Ref node, bool pretty) {
  std::cerr << str << ": ";
  if (!!node) {
    node->stringify(std::cerr, pretty);
  } else {
    std::cerr << "(nullptr)";
  }
  std::cerr << std::endl;
}

} // namespace cashew
