/*
 * 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.
 */

#ifndef AIDL_AST_CPP_H_
#define AIDL_AST_CPP_H_

#include <memory>
#include <string>
#include <vector>

#include <android-base/macros.h>

namespace android {
namespace aidl {
class CodeWriter;
}  // namespace aidl
}  // namespace android

namespace android {
namespace aidl {
namespace cpp {

class AstNode {
 public:
  AstNode() = default;
  virtual ~AstNode() = default;
  virtual void Write(CodeWriter* to) const = 0;
};  // class AstNode

class Declaration : public AstNode {
 public:
  Declaration() = default;
  virtual ~Declaration() = default;

 private:
  DISALLOW_COPY_AND_ASSIGN(Declaration);
};  // class Declaration

class ClassDecl : public Declaration {
 public:
  ClassDecl(const std::string& name,
            const std::string& parent);
  ClassDecl(const std::string& name,
            const std::string& parent,
            std::vector<std::unique_ptr<Declaration>> public_members,
            std::vector<std::unique_ptr<Declaration>> private_members);
  virtual ~ClassDecl() = default;

  void Write(CodeWriter* to) const override;

  void AddPublic(std::unique_ptr<Declaration> member);
  void AddPrivate(std::unique_ptr<Declaration> member);

 private:
  std::string name_;
  std::string parent_;
  std::vector<std::unique_ptr<Declaration>> public_members_;
  std::vector<std::unique_ptr<Declaration>> private_members_;

  DISALLOW_COPY_AND_ASSIGN(ClassDecl);
};  // class ClassDecl

class Enum : public Declaration {
 public:
  Enum(const std::string& name, const std::string& base_type);
  explicit Enum(const std::string& name);
  virtual ~Enum() = default;

  bool HasValues() const { return !fields_.empty(); }
  void Write(CodeWriter* to) const override;

  void AddValue(const std::string& key, const std::string& value);

 private:
  struct EnumField {
    EnumField(const std::string& k, const std::string& v);
    const std::string key;
    const std::string value;
  };

  std::string enum_name_;
  std::string underlying_type_;
  std::vector<EnumField> fields_;

  DISALLOW_COPY_AND_ASSIGN(Enum);
};  // class Enum

class ArgList : public AstNode {
 public:
  ArgList() = default;
  explicit ArgList(const std::string& single_argument);
  explicit ArgList(const std::vector<std::string>& arg_list);
  explicit ArgList(std::vector<std::unique_ptr<AstNode>> arg_list);
  ArgList(ArgList&& arg_list);
  virtual ~ArgList() = default;

  void Write(CodeWriter* to) const override;

 private:
  std::vector<std::unique_ptr<AstNode>> arguments_;

  DISALLOW_COPY_AND_ASSIGN(ArgList);
};  // class ArgList

class ConstructorDecl : public Declaration {
 public:
  enum Modifiers {
    IS_VIRTUAL = 1 << 0,
    IS_DEFAULT = 1 << 1,
    IS_EXPLICIT = 1 << 2,
  };

  ConstructorDecl(const std::string& name,
                  ArgList&& arg_list);
  ConstructorDecl(const std::string& name,
                  ArgList&& arg_list,
                  uint32_t modifiers);

  virtual ~ConstructorDecl() = default;

  void Write(CodeWriter* to) const override;

 private:
  const std::string name_;
  const ArgList arguments_;
  const uint32_t modifiers_;

  DISALLOW_COPY_AND_ASSIGN(ConstructorDecl);
};  // class ConstructorDecl

class MacroDecl : public Declaration {
 public:
  MacroDecl(const std::string& name, ArgList&& arg_list);
  virtual ~MacroDecl() = default;

  void Write(CodeWriter* to) const override;

 private:
  const std::string name_;
  const ArgList arguments_;

  DISALLOW_COPY_AND_ASSIGN(MacroDecl);
};  // class MacroDecl

class MethodDecl : public Declaration {
 public:
  enum Modifiers {
    IS_CONST = 1 << 0,
    IS_VIRTUAL = 1 << 1,
    IS_OVERRIDE = 1 << 2,
    IS_PURE_VIRTUAL = 1 << 3,
    IS_STATIC = 1 << 4,
  };

  MethodDecl(const std::string& return_type,
             const std::string& name,
             ArgList&& arg_list);
  MethodDecl(const std::string& return_type,
             const std::string& name,
             ArgList&& arg_list,
             uint32_t modifiers);
  virtual ~MethodDecl() = default;

  void Write(CodeWriter* to) const override;

 private:
  const std::string return_type_;
  const std::string name_;
  const ArgList arguments_;
  bool is_const_ = false;
  bool is_virtual_ = false;
  bool is_override_ = false;
  bool is_pure_virtual_ = false;
  bool is_static_ = true;

  DISALLOW_COPY_AND_ASSIGN(MethodDecl);
};  // class MethodDecl

class StatementBlock : public Declaration {
 public:
  StatementBlock() = default;
  virtual ~StatementBlock() = default;

  void AddStatement(std::unique_ptr<AstNode> statement);
  void AddStatement(AstNode* statement);  // Takes ownership
  void AddLiteral(const std::string& expression, bool add_semicolon = true);
  bool Empty() const { return statements_.empty(); }

  void Write(CodeWriter* to) const override;

 private:
  std::vector<std::unique_ptr<AstNode>> statements_;

  DISALLOW_COPY_AND_ASSIGN(StatementBlock);
};  // class StatementBlock

class ConstructorImpl : public Declaration {
 public:
  ConstructorImpl(const std::string& class_name,
                  ArgList&& arg_list,
                  const std::vector<std::string>& initializer_list);
  virtual ~ConstructorImpl() = default;

  void Write(CodeWriter* to) const override;

 private:
  std::string class_name_;
  ArgList arguments_;
  std::vector<std::string> initializer_list_;
  StatementBlock body_;

  DISALLOW_COPY_AND_ASSIGN(ConstructorImpl);
};  // class ConstructorImpl

class MethodImpl : public Declaration {
 public:
  // Passing an empty class name causes the method to be declared as a normal
  // function (ie. no ClassName:: qualifier).
  MethodImpl(const std::string& return_type,
             const std::string& class_name,
             const std::string& method_name,
             ArgList&& arg_list,
             bool is_const_method = false);
  virtual ~MethodImpl() = default;

  // MethodImpl retains ownership of the statement block.
  StatementBlock* GetStatementBlock();

  void Write(CodeWriter* to) const override;

 private:
  std::string return_type_;
  std::string method_name_;
  const ArgList arguments_;
  StatementBlock statements_;
  bool is_const_method_ = false;

  DISALLOW_COPY_AND_ASSIGN(MethodImpl);
};  // class MethodImpl

class SwitchStatement : public AstNode {
 public:
  explicit SwitchStatement(const std::string& expression);
  virtual ~SwitchStatement() = default;

  // Add a case statement and return a pointer code block corresponding
  // to the case.  The switch statement will add a break statement
  // after the code block by default to prevent accidental fall-through.
  // Returns nullptr on duplicate value expressions (by strcmp, not value
  // equivalence).
  StatementBlock* AddCase(const std::string& value_expression);
  void Write(CodeWriter* to) const override;

 private:
  const std::string switch_expression_;
  std::vector<std::string> case_values_;
  std::vector<std::unique_ptr<StatementBlock>> case_logic_;

  DISALLOW_COPY_AND_ASSIGN(SwitchStatement);
};  // class SwitchStatement

class Assignment : public AstNode {
 public:
  Assignment(const std::string& left, const std::string& right);
  Assignment(const std::string& left, AstNode* right);
  ~Assignment() = default;
  void Write(CodeWriter* to) const override;

 private:
  const std::string lhs_;
  std::unique_ptr<AstNode> rhs_;

  DISALLOW_COPY_AND_ASSIGN(Assignment);
};  // class Assignment

class MethodCall : public AstNode {
 public:
  MethodCall(const std::string& method_name,
             const std::string& single_argument);
  MethodCall(const std::string& method_name, ArgList&& arg_list);
  ~MethodCall() = default;
  void Write(CodeWriter* to) const override;

 private:
  const std::string method_name_;
  const ArgList arguments_;

  DISALLOW_COPY_AND_ASSIGN(MethodCall);
};  // class MethodCall

class IfStatement : public AstNode {
 public:
  explicit IfStatement(AstNode* expression,
              bool invert_expression = false);
  virtual ~IfStatement() = default;
  StatementBlock* OnTrue() { return &on_true_; }
  StatementBlock* OnFalse() { return &on_false_; }
  void Write(CodeWriter* to) const override;

 private:
  std::unique_ptr<AstNode> expression_;
  bool invert_expression_ = false;
  StatementBlock on_true_;
  StatementBlock on_false_;

  DISALLOW_COPY_AND_ASSIGN(IfStatement);
};  // class IfStatement

class Statement : public AstNode {
 public:
  explicit Statement(std::unique_ptr<AstNode> expression);
  explicit Statement(AstNode* expression);  // Takes possession.
  explicit Statement(const std::string& expression);
  ~Statement() = default;
  void Write(CodeWriter* to) const override;

 private:
  std::unique_ptr<AstNode> expression_;

  DISALLOW_COPY_AND_ASSIGN(Statement);
};  // class Statement

class Comparison : public AstNode {
 public:
  Comparison(AstNode* lhs, const std::string& comparison, AstNode* rhs);
  ~Comparison() = default;
  void Write(CodeWriter* to) const override;

 private:
  std::unique_ptr<AstNode> left_;
  std::unique_ptr<AstNode> right_;
  const std::string operator_;

  DISALLOW_COPY_AND_ASSIGN(Comparison);
};  // class Comparison

class LiteralExpression : public AstNode {
 public:
  explicit LiteralExpression(const std::string& expression);
  ~LiteralExpression() = default;
  void Write(CodeWriter* to) const override;

 private:
  const std::string expression_;

  DISALLOW_COPY_AND_ASSIGN(LiteralExpression);
};  // class LiteralExpression

class CppNamespace : public Declaration {
 public:
  CppNamespace(const std::string& name,
               std::vector<std::unique_ptr<Declaration>> declarations);
  CppNamespace(const std::string& name,
               std::unique_ptr<Declaration> declaration);
  explicit CppNamespace(const std::string& name);
  virtual ~CppNamespace() = default;

  void Write(CodeWriter* to) const override;

 private:
  std::vector<std::unique_ptr<Declaration>> declarations_;
  std::string name_;

  DISALLOW_COPY_AND_ASSIGN(CppNamespace);
};  // class CppNamespace

class Document : public AstNode {
 public:
  Document(const std::vector<std::string>& include_list,
           std::unique_ptr<CppNamespace> a_namespace);

  void Write(CodeWriter* to) const override;

 private:
  std::vector<std::string> include_list_;
  std::unique_ptr<CppNamespace> namespace_;

  DISALLOW_COPY_AND_ASSIGN(Document);
};  // class Document

class CppHeader final : public Document {
 public:
  CppHeader(const std::string& include_guard,
            const std::vector<std::string>& include_list,
            std::unique_ptr<CppNamespace> a_namespace);
  void Write(CodeWriter* to) const override;

 private:
  const std::string include_guard_;

  DISALLOW_COPY_AND_ASSIGN(CppHeader);
};  // class CppHeader

class CppSource final : public Document {
 public:
  CppSource(const std::vector<std::string>& include_list,
            std::unique_ptr<CppNamespace> a_namespace);

 private:
  DISALLOW_COPY_AND_ASSIGN(CppSource);
};  // class CppSource

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

#endif // AIDL_AST_CPP_H_
