/*
 * Copyright (C) 2015, The Android Open Source Project
 *
 * 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 "ast_java.h"
#include "code_writer.h"

using std::vector;
using std::string;

template <class... Ts>
struct overloaded : Ts... {
  using Ts::operator()...;
};
template <class... Ts>
overloaded(Ts...)->overloaded<Ts...>;

namespace android {
namespace aidl {
namespace java {

std::string AstNode::ToString() {
  std::string str;
  Write(CodeWriter::ForString(&str).get());
  return str;
}

void WriteComment(CodeWriter* to, const std::string& comment) {
  to->Write("%s", comment.c_str());
  if (!comment.empty() && comment.back() != '\n') to->Write("\n");
}

void WriteModifiers(CodeWriter* to, int mod, int mask) {
  int m = mod & mask;

  if (m & OVERRIDE) {
    to->Write("@Override ");
  }

  if ((m & SCOPE_MASK) == PUBLIC) {
    to->Write("public ");
  } else if ((m & SCOPE_MASK) == PRIVATE) {
    to->Write("private ");
  } else if ((m & SCOPE_MASK) == PROTECTED) {
    to->Write("protected ");
  }

  if (m & STATIC) {
    to->Write("static ");
  }

  if (m & FINAL) {
    to->Write("final ");
  }

  if (m & ABSTRACT) {
    to->Write("abstract ");
  }
}

void WriteArgumentList(CodeWriter* to, const vector<std::shared_ptr<Expression>>& arguments) {
  size_t N = arguments.size();
  for (size_t i = 0; i < N; i++) {
    arguments[i]->Write(to);
    if (i != N - 1) {
      to->Write(", ");
    }
  }
}

Field::Field(int m, std::shared_ptr<Variable> v) : ClassElement(), modifiers(m), variable(v) {}

void Field::Write(CodeWriter* to) const {
  WriteComment(to, comment);
  for (const auto& a : this->annotations) {
    to->Write("%s\n", a.c_str());
  }
  WriteModifiers(to, this->modifiers, SCOPE_MASK | STATIC | FINAL | OVERRIDE);
  this->variable->WriteDeclaration(to);

  if (this->value.length() != 0) {
    to->Write(" = %s", this->value.c_str());
  }
  to->Write(";\n");
}

LiteralExpression::LiteralExpression(const string& v) : value(v) {}

void LiteralExpression::Write(CodeWriter* to) const {
  to->Write("%s", this->value.c_str());
}

StringLiteralExpression::StringLiteralExpression(const string& v) : value(v) {}

void StringLiteralExpression::Write(CodeWriter* to) const {
  to->Write("\"%s\"", this->value.c_str());
}

Variable::Variable(const string& t, const string& n) : type(t), name(n) {}

void Variable::WriteDeclaration(CodeWriter* to) const {
  for (const auto& a : this->annotations) {
    to->Write("%s ", a.c_str());
  }
  to->Write("%s %s", this->type.c_str(), this->name.c_str());
}

void Variable::Write(CodeWriter* to) const { to->Write("%s", name.c_str()); }

FieldVariable::FieldVariable(std::shared_ptr<Expression> o, const string& n)
    : receiver(o), name(n) {}

FieldVariable::FieldVariable(const string& c, const string& n) : receiver(c), name(n) {}

void FieldVariable::Write(CodeWriter* to) const {
  visit(
      overloaded{[&](std::shared_ptr<Expression> e) { e->Write(to); },
                 [&](const std::string& s) { to->Write("%s", s.c_str()); }, [](std::monostate) {}},
      this->receiver);
  to->Write(".%s", name.c_str());
}

LiteralStatement::LiteralStatement(const std::string& value) : value_(value) {}

void LiteralStatement::Write(CodeWriter* to) const {
  to->Write("%s", value_.c_str());
}

void StatementBlock::Write(CodeWriter* to) const {
  to->Write("{\n");
  to->Indent();
  int N = this->statements.size();
  for (int i = 0; i < N; i++) {
    this->statements[i]->Write(to);
  }
  to->Dedent();
  to->Write("}\n");
}

void StatementBlock::Add(std::shared_ptr<Statement> statement) {
  this->statements.push_back(statement);
}

void StatementBlock::Add(std::shared_ptr<Expression> expression) {
  this->statements.push_back(std::make_shared<ExpressionStatement>(expression));
}

ExpressionStatement::ExpressionStatement(std::shared_ptr<Expression> e) : expression(e) {}

void ExpressionStatement::Write(CodeWriter* to) const {
  this->expression->Write(to);
  to->Write(";\n");
}

Assignment::Assignment(std::shared_ptr<Variable> l, std::shared_ptr<Expression> r)
    : lvalue(l), rvalue(r) {}

Assignment::Assignment(std::shared_ptr<Variable> l, std::shared_ptr<Expression> r, string c)
    : lvalue(l), rvalue(r), cast(c) {}

void Assignment::Write(CodeWriter* to) const {
  this->lvalue->Write(to);
  to->Write(" = ");
  if (this->cast) {
    to->Write("(%s)", this->cast->c_str());
  }
  this->rvalue->Write(to);
}

MethodCall::MethodCall(const string& n) : name(n) {}

MethodCall::MethodCall(const string& n, const std::vector<std::shared_ptr<Expression>>& args)
    : name(n), arguments(args) {}

MethodCall::MethodCall(std::shared_ptr<Expression> o, const string& n) : receiver(o), name(n) {}

MethodCall::MethodCall(const std::string& t, const string& n) : receiver(t), name(n) {}

MethodCall::MethodCall(std::shared_ptr<Expression> o, const string& n,
                       const std::vector<std::shared_ptr<Expression>>& args)
    : receiver(o), name(n), arguments(args) {}

MethodCall::MethodCall(const std::string& t, const string& n,
                       const std::vector<std::shared_ptr<Expression>>& args)
    : receiver(t), name(n), arguments(args) {}

void MethodCall::Write(CodeWriter* to) const {
  visit(
      overloaded{[&](std::shared_ptr<Expression> e) {
                   e->Write(to);
                   to->Write(".");
                 },
                 [&](const std::string& s) { to->Write("%s.", s.c_str()); }, [](std::monostate) {}},
      this->receiver);
  to->Write("%s(", this->name.c_str());
  WriteArgumentList(to, this->arguments);
  to->Write(")");
}

Comparison::Comparison(std::shared_ptr<Expression> l, const string& o,
                       std::shared_ptr<Expression> r)
    : lvalue(l), op(o), rvalue(r) {}

void Comparison::Write(CodeWriter* to) const {
  to->Write("(");
  this->lvalue->Write(to);
  to->Write("%s", this->op.c_str());
  this->rvalue->Write(to);
  to->Write(")");
}

NewExpression::NewExpression(const std::string& n) : instantiableName(n) {}

NewExpression::NewExpression(const std::string& n,
                             const std::vector<std::shared_ptr<Expression>>& args)
    : instantiableName(n), arguments(args) {}

void NewExpression::Write(CodeWriter* to) const {
  to->Write("new %s(", this->instantiableName.c_str());
  WriteArgumentList(to, this->arguments);
  to->Write(")");
}

NewArrayExpression::NewArrayExpression(const std::string& t, std::shared_ptr<Expression> s)
    : type(t), size(s) {}

void NewArrayExpression::Write(CodeWriter* to) const {
  to->Write("new %s[", this->type.c_str());
  size->Write(to);
  to->Write("]");
}

Cast::Cast(const std::string& t, std::shared_ptr<Expression> e) : type(t), expression(e) {}

void Cast::Write(CodeWriter* to) const {
  to->Write("((%s)", this->type.c_str());
  expression->Write(to);
  to->Write(")");
}

VariableDeclaration::VariableDeclaration(std::shared_ptr<Variable> l, std::shared_ptr<Expression> r)
    : lvalue(l), rvalue(r) {}

VariableDeclaration::VariableDeclaration(std::shared_ptr<Variable> l) : lvalue(l) {}

void VariableDeclaration::Write(CodeWriter* to) const {
  this->lvalue->WriteDeclaration(to);
  if (this->rvalue != nullptr) {
    to->Write(" = ");
    this->rvalue->Write(to);
  }
  to->Write(";\n");
}

void IfStatement::Write(CodeWriter* to) const {
  if (this->expression != nullptr) {
    to->Write("if (");
    this->expression->Write(to);
    to->Write(") ");
  }
  this->statements->Write(to);
  if (this->elseif != nullptr) {
    to->Write("else ");
    this->elseif->Write(to);
  }
}

ReturnStatement::ReturnStatement(std::shared_ptr<Expression> e) : expression(e) {}

void ReturnStatement::Write(CodeWriter* to) const {
  to->Write("return ");
  this->expression->Write(to);
  to->Write(";\n");
}

void BreakStatement::Write(CodeWriter* to) const {
  to->Write("break;\n");
}

void TryStatement::Write(CodeWriter* to) const {
  to->Write("try ");
  this->statements->Write(to);
}

void FinallyStatement::Write(CodeWriter* to) const {
  to->Write("finally ");
  this->statements->Write(to);
}

Case::Case(const string& c) { cases.push_back(c); }

void Case::Write(CodeWriter* to) const {
  int N = this->cases.size();
  if (N > 0) {
    for (int i = 0; i < N; i++) {
      string s = this->cases[i];
      if (s.length() != 0) {
        to->Write("case %s:\n", s.c_str());
      } else {
        to->Write("default:\n");
      }
    }
  } else {
    to->Write("default:\n");
  }
  statements->Write(to);
}

SwitchStatement::SwitchStatement(std::shared_ptr<Expression> e) : expression(e) {}

void SwitchStatement::Write(CodeWriter* to) const {
  to->Write("switch (");
  this->expression->Write(to);
  to->Write(")\n{\n");
  to->Indent();
  int N = this->cases.size();
  for (int i = 0; i < N; i++) {
    this->cases[i]->Write(to);
  }
  to->Dedent();
  to->Write("}\n");
}

void Method::Write(CodeWriter* to) const {
  size_t N, i;

  WriteComment(to, comment);

  for (const auto& a : this->annotations) {
    to->Write("%s\n", a.c_str());
  }

  WriteModifiers(to, this->modifiers,
                 SCOPE_MASK | STATIC | ABSTRACT | FINAL | OVERRIDE);

  if (this->returnType) {
    to->Write("%s ", this->returnType->c_str());
  }

  to->Write("%s(", this->name.c_str());

  N = this->parameters.size();
  for (i = 0; i < N; i++) {
    this->parameters[i]->WriteDeclaration(to);
    if (i != N - 1) {
      to->Write(", ");
    }
  }

  to->Write(")");

  N = this->exceptions.size();
  for (i = 0; i < N; i++) {
    if (i == 0) {
      to->Write(" throws ");
    } else {
      to->Write(", ");
    }
    to->Write("%s", this->exceptions[i].c_str());
  }

  if (this->statements == nullptr) {
    to->Write(";\n");
  } else {
    to->Write("\n");
    this->statements->Write(to);
  }
}

void LiteralClassElement::Write(CodeWriter* to) const {
  to->Write("%s", element.c_str());
}

void Class::Write(CodeWriter* to) const {
  size_t N, i;

  WriteComment(to, comment);
  for (const auto& a : this->annotations) {
    to->Write("%s\n", a.c_str());
  }

  WriteModifiers(to, this->modifiers, ALL_MODIFIERS);

  if (this->what == Class::CLASS) {
    to->Write("class ");
  } else {
    to->Write("interface ");
  }

  string name = this->type;
  size_t pos = name.rfind('.');
  if (pos != string::npos) {
    name = name.c_str() + pos + 1;
  }

  to->Write("%s", name.c_str());

  if (this->extends) {
    to->Write(" extends %s", this->extends->c_str());
  }

  N = this->interfaces.size();
  if (N != 0) {
    if (this->what == Class::CLASS) {
      to->Write(" implements");
    } else {
      to->Write(" extends");
    }
    for (i = 0; i < N; i++) {
      to->Write(" %s", this->interfaces[i].c_str());
    }
  }

  to->Write("\n");
  to->Write("{\n");
  to->Indent();

  N = this->elements.size();
  for (i = 0; i < N; i++) {
    this->elements[i]->Write(to);
  }

  to->Dedent();
  to->Write("}\n");
}

std::shared_ptr<Expression> NULL_VALUE = std::make_shared<LiteralExpression>("null");
std::shared_ptr<Expression> THIS_VALUE = std::make_shared<LiteralExpression>("this");
std::shared_ptr<Expression> SUPER_VALUE = std::make_shared<LiteralExpression>("super");
std::shared_ptr<Expression> TRUE_VALUE = std::make_shared<LiteralExpression>("true");
std::shared_ptr<Expression> FALSE_VALUE = std::make_shared<LiteralExpression>("false");
}  // namespace java
}  // namespace aidl
}  // namespace android
