/*
 * 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_cpp.h"

#include <algorithm>

#include "code_writer.h"
#include "logging.h"

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

namespace android {
namespace aidl {
namespace cpp {

ClassDecl::ClassDecl(const std::string& name, const std::string& parent)
    : name_(name),
      parent_(parent) {}

ClassDecl::ClassDecl(const std::string& name, const std::string& parent,
                     std::vector<unique_ptr<Declaration>> public_members,
                     std::vector<unique_ptr<Declaration>> private_members)
    : name_(name),
      parent_(parent),
      public_members_(std::move(public_members)),
      private_members_(std::move(private_members)) {}

void ClassDecl::Write(CodeWriter* to) const {
  to->Write("class %s ", name_.c_str());

  if (parent_.length() > 0)
      to->Write(": public %s ", parent_.c_str());

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

  if (!public_members_.empty())
      to->Write("public:\n");

  for (const auto& dec : public_members_)
    dec->Write(to);

  if (!private_members_.empty())
      to->Write("private:\n");

  for (const auto& dec : private_members_)
    dec->Write(to);

  to->Write("};  // class %s\n", name_.c_str());
}

void ClassDecl::AddPublic(std::unique_ptr<Declaration> member) {
  public_members_.push_back(std::move(member));
}

void ClassDecl::AddPrivate(std::unique_ptr<Declaration> member) {
  private_members_.push_back(std::move(member));
}

Enum::EnumField::EnumField(const string& k, const string&v)
    : key(k),
      value(v) {}

Enum::Enum(const string& name) : enum_name_(name) {}

void Enum::Write(CodeWriter* to) const {
  to->Write("enum %s {\n", enum_name_.c_str());
  for (const auto& field : fields_) {
    if (field.value.empty()) {
      to->Write("  %s,\n", field.key.c_str());
    } else {
      to->Write("  %s = %s,\n", field.key.c_str(), field.value.c_str());
    }
  }
  to->Write("};\n");
}

void Enum::AddValue(const string& key, const string& value) {
  fields_.emplace_back(key, value);
}

ArgList::ArgList(const std::string& single_argument)
    : ArgList(vector<string>{single_argument}) {}

ArgList::ArgList(const std::vector<std::string>& arg_list)
    : arguments_(arg_list) {}

ArgList::ArgList(ArgList&& arg_list)
    : arguments_(std::move(arg_list.arguments_)) {}

void ArgList::Write(CodeWriter* to) const {
  to->Write("(");
  bool is_first = true;
  for (const auto& s : arguments_) {
    if (!is_first) { to->Write(", "); }
    is_first = false;
    to->Write("%s", s.c_str());
  }
  to->Write(")");
}

ConstructorDecl::ConstructorDecl(
    const std::string& name,
    ArgList&& arg_list)
    : ConstructorDecl(name, std::move(arg_list), 0u) {}

ConstructorDecl::ConstructorDecl(
    const std::string& name,
    ArgList&& arg_list,
    uint32_t modifiers)
    : name_(name),
      arguments_(std::move(arg_list)),
      modifiers_(modifiers) {}

void ConstructorDecl::Write(CodeWriter* to) const {
  if (modifiers_ & Modifiers::IS_VIRTUAL)
    to->Write("virtual ");

  if (modifiers_ & Modifiers::IS_EXPLICIT)
    to->Write("explicit ");

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

  arguments_.Write(to);

  if (modifiers_ & Modifiers::IS_DEFAULT)
    to->Write(" = default");

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

MethodDecl::MethodDecl(const std::string& return_type,
                       const std::string& name,
                       ArgList&& arg_list)
    : MethodDecl(return_type, name, std::move(arg_list), 0u) {}

MethodDecl::MethodDecl(const std::string& return_type,
                       const std::string& name,
                       ArgList&& arg_list,
                       uint32_t modifiers)
    : return_type_(return_type),
      name_(name),
      arguments_(std::move(arg_list)),
      is_const_(modifiers & IS_CONST),
      is_virtual_(modifiers & IS_VIRTUAL),
      is_override_(modifiers & IS_OVERRIDE),
      is_pure_virtual_(modifiers & IS_PURE_VIRTUAL) {}

void MethodDecl::Write(CodeWriter* to) const {
  if (is_virtual_)
    to->Write("virtual ");

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

  arguments_.Write(to);

  if (is_const_)
    to->Write(" const");

  if (is_override_)
    to->Write(" override");

  if (is_pure_virtual_)
    to->Write(" = 0");

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

void StatementBlock::AddStatement(unique_ptr<AstNode> statement) {
  statements_.push_back(std::move(statement));
}

void StatementBlock::AddStatement(AstNode* statement) {
  statements_.emplace_back(statement);
}

void StatementBlock::AddLiteral(const std::string& expression_str,
                                bool add_semicolon) {
  if (add_semicolon) {
    statements_.push_back(unique_ptr<AstNode>(new Statement(expression_str)));
  } else {
    statements_.push_back(unique_ptr<AstNode>(
        new LiteralExpression(expression_str)));
  }
}

void StatementBlock::Write(CodeWriter* to) const {
  to->Write("{\n");
  for (const auto& statement : statements_) {
    statement->Write(to);
  }
  to->Write("}\n");
}

ConstructorImpl::ConstructorImpl(const string& class_name,
                                 ArgList&& arg_list,
                                 const vector<string>& initializer_list)
      : class_name_(class_name),
        arguments_(std::move(arg_list)),
        initializer_list_(initializer_list) {}

void ConstructorImpl::Write(CodeWriter* to) const {
  to->Write("%s::%s", class_name_.c_str(), class_name_.c_str());
  arguments_.Write(to);
  to->Write("\n");

  bool is_first = true;
  for (const string& i : initializer_list_) {
    if (is_first) {
      to->Write("    : %s", i.c_str());
    } else {
      to->Write(",\n      %s", i.c_str());
    }
    is_first = false;
  }

  body_.Write(to);
}

MethodImpl::MethodImpl(const string& return_type,
                       const string& class_name,
                       const string& method_name,
                       ArgList&& arg_list,
                       bool is_const_method)
    : return_type_(return_type),
      method_name_(method_name),
      arguments_(std::move(arg_list)),
      is_const_method_(is_const_method) {
  if (!class_name.empty()) {
    method_name_ = class_name + "::" + method_name;
  }
}

StatementBlock* MethodImpl::GetStatementBlock() {
  return &statements_;
}

void MethodImpl::Write(CodeWriter* to) const {
  to->Write("%s %s", return_type_.c_str(), method_name_.c_str());
  arguments_.Write(to);
  to->Write("%s ", (is_const_method_) ? " const" : "");
  statements_.Write(to);
}

SwitchStatement::SwitchStatement(const std::string& expression)
    : switch_expression_(expression) {}

StatementBlock* SwitchStatement::AddCase(const string& value_expression) {
  auto it = std::find(case_values_.begin(), case_values_.end(), value_expression);
  if (it != case_values_.end()) {
    LOG(ERROR) << "internal error: duplicate switch case labels";
    return nullptr;
  }
  StatementBlock* ret = new StatementBlock();
  case_values_.push_back(value_expression);
  case_logic_.push_back(unique_ptr<StatementBlock>{ret});
  return ret;
}

void SwitchStatement::Write(CodeWriter* to) const {
  to->Write("switch (%s) {\n", switch_expression_.c_str());
  for (size_t i = 0; i < case_values_.size(); ++i) {
    const string& case_value = case_values_[i];
    const unique_ptr<StatementBlock>& statements = case_logic_[i];
    if (case_value.empty()) {
      to->Write("default:\n");
    } else {
      to->Write("case %s:\n", case_value.c_str());
    }
    statements->Write(to);
    to->Write("break;\n");
  }
  to->Write("}\n");
}


Assignment::Assignment(const std::string& left, const std::string& right)
    : Assignment(left, new LiteralExpression{right}) {}

Assignment::Assignment(const std::string& left, AstNode* right)
    : lhs_(left),
      rhs_(right) {}

void Assignment::Write(CodeWriter* to) const {
  to->Write("%s = ", lhs_.c_str());
  rhs_->Write(to);
  to->Write(";\n");
}

MethodCall::MethodCall(const std::string& method_name,
                       const std::string& single_argument)
    : MethodCall(method_name, ArgList{single_argument}) {}

MethodCall::MethodCall(const std::string& method_name,
                       ArgList&& arg_list)
    : method_name_(method_name),
      arguments_{std::move(arg_list)} {}

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

IfStatement::IfStatement(AstNode* expression, bool invert_expression)
    : expression_(expression),
      invert_expression_(invert_expression) {}

void IfStatement::Write(CodeWriter* to) const {
  to->Write("if (%s", (invert_expression_) ? "(!" : "");
  expression_->Write(to);
  to->Write(")%s ", (invert_expression_) ? ")" : "");
  on_true_.Write(to);

  if (!on_false_.Empty()) {
    to->Write("else ");
    on_false_.Write(to);
  }
}

Statement::Statement(unique_ptr<AstNode> expression)
    : expression_(std::move(expression)) {}

Statement::Statement(AstNode* expression) : expression_(expression) {}

Statement::Statement(const string& expression)
    : expression_(new LiteralExpression(expression)) {}

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

Comparison::Comparison(AstNode* lhs, const string& comparison, AstNode* rhs)
    : left_(lhs),
      right_(rhs),
      operator_(comparison) {}

void Comparison::Write(CodeWriter* to) const {
  to->Write("((");
  left_->Write(to);
  to->Write(") %s (", operator_.c_str());
  right_->Write(to);
  to->Write("))");
}

LiteralExpression::LiteralExpression(const std::string& expression)
    : expression_(expression) {}

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

CppNamespace::CppNamespace(const std::string& name,
                           std::vector<unique_ptr<Declaration>> declarations)
    : declarations_(std::move(declarations)),
      name_(name) {}

CppNamespace::CppNamespace(const std::string& name,
                           unique_ptr<Declaration> declaration)
    : name_(name) {
  declarations_.push_back(std::move(declaration));
}
CppNamespace::CppNamespace(const std::string& name)
    : name_(name) {}

void CppNamespace::Write(CodeWriter* to) const {
  to->Write("namespace %s {\n\n", name_.c_str());

  for (const auto& dec : declarations_) {
    dec->Write(to);
    to->Write("\n");
  }

  to->Write("}  // namespace %s\n", name_.c_str());
}

Document::Document(const std::vector<std::string>& include_list,
                   unique_ptr<CppNamespace> a_namespace)
    : include_list_(include_list),
      namespace_(std::move(a_namespace)) {}

void Document::Write(CodeWriter* to) const {
  for (const auto& include : include_list_) {
    to->Write("#include <%s>\n", include.c_str());
  }
  to->Write("\n");

  namespace_->Write(to);
}

CppHeader::CppHeader(const std::string& include_guard,
                     const std::vector<std::string>& include_list,
                     unique_ptr<CppNamespace> a_namespace)
    : Document(include_list, std::move(a_namespace)),
      include_guard_(include_guard) {}

void CppHeader::Write(CodeWriter* to) const {
  to->Write("#ifndef %s\n", include_guard_.c_str());
  to->Write("#define %s\n\n", include_guard_.c_str());

  Document::Write(to);
  to->Write("\n");

  to->Write("#endif  // %s", include_guard_.c_str());
}

CppSource::CppSource(const std::vector<std::string>& include_list,
                     unique_ptr<CppNamespace> a_namespace)
    : Document(include_list, std::move(a_namespace)) {}

}  // namespace cpp
}  // namespace aidl
}  // namespace android
