//===- unittest/Tooling/CommentHandlerTest.cpp -----------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "TestVisitor.h"
#include "clang/Lex/Preprocessor.h"

namespace clang {

struct Comment {
  Comment(const std::string &Message, unsigned Line, unsigned Col)
    : Message(Message), Line(Line), Col(Col) { }

  std::string Message;
  unsigned Line, Col;
};

class CommentVerifier;
typedef std::vector<Comment> CommentList;

class CommentHandlerVisitor : public TestVisitor<CommentHandlerVisitor>,
                              public CommentHandler {
  typedef TestVisitor<CommentHandlerVisitor> base;

public:
  CommentHandlerVisitor() : base(), PP(nullptr), Verified(false) {}

  ~CommentHandlerVisitor() {
    EXPECT_TRUE(Verified) << "CommentVerifier not accessed";
  }

  virtual bool HandleComment(Preprocessor &PP, SourceRange Loc) {
    assert(&PP == this->PP && "Preprocessor changed!");

    SourceLocation Start = Loc.getBegin();
    SourceManager &SM = PP.getSourceManager();
    std::string C(SM.getCharacterData(Start),
                  SM.getCharacterData(Loc.getEnd()));

    bool Invalid;
    unsigned CLine = SM.getSpellingLineNumber(Start, &Invalid);
    EXPECT_TRUE(!Invalid) << "Invalid line number on comment " << C;

    unsigned CCol = SM.getSpellingColumnNumber(Start, &Invalid);
    EXPECT_TRUE(!Invalid) << "Invalid column number on comment " << C;

    Comments.push_back(Comment(C, CLine, CCol));
    return false;
  }

  CommentVerifier GetVerifier();

protected:
  virtual ASTFrontendAction* CreateTestAction() {
    return new CommentHandlerAction(this);
  }

private:
  Preprocessor *PP;
  CommentList Comments;
  bool Verified;

  class CommentHandlerAction : public base::TestAction {
  public:
    CommentHandlerAction(CommentHandlerVisitor *Visitor)
        : TestAction(Visitor) { }

    virtual bool BeginSourceFileAction(CompilerInstance &CI,
                                       StringRef FileName) {
      CommentHandlerVisitor *V =
          static_cast<CommentHandlerVisitor*>(this->Visitor);
      V->PP = &CI.getPreprocessor();
      V->PP->addCommentHandler(V);
      return true;
    }

    virtual void EndSourceFileAction() {
      CommentHandlerVisitor *V =
          static_cast<CommentHandlerVisitor*>(this->Visitor);
      V->PP->removeCommentHandler(V);
    }
  };
};

class CommentVerifier {
  CommentList::const_iterator Current;
  CommentList::const_iterator End;
  Preprocessor *PP;

public:
  CommentVerifier(const CommentList &Comments, Preprocessor *PP)
      : Current(Comments.begin()), End(Comments.end()), PP(PP)
    { }

  ~CommentVerifier() {
    if (Current != End) {
      EXPECT_TRUE(Current == End) << "Unexpected comment \""
        << Current->Message << "\" at line " << Current->Line << ", column "
        << Current->Col;
    }
  }

  void Match(const char *Message, unsigned Line, unsigned Col) {
    EXPECT_TRUE(Current != End) << "Comment " << Message << " not found";
    if (Current == End) return;

    const Comment &C = *Current;
    EXPECT_TRUE(C.Message == Message && C.Line == Line && C.Col == Col)
      <<   "Expected comment \"" << Message
      << "\" at line " << Line   << ", column " << Col
      << "\nActual comment   \"" << C.Message
      << "\" at line " << C.Line << ", column " << C.Col;

    ++Current;
  }
};

CommentVerifier CommentHandlerVisitor::GetVerifier() {
  Verified = true;
  return CommentVerifier(Comments, PP);
}


TEST(CommentHandlerTest, BasicTest1) {
  CommentHandlerVisitor Visitor;
  EXPECT_TRUE(Visitor.runOver("class X {}; int main() { return 0; }"));
  CommentVerifier Verifier = Visitor.GetVerifier();
}

TEST(CommentHandlerTest, BasicTest2) {
  CommentHandlerVisitor Visitor;
  EXPECT_TRUE(Visitor.runOver(
        "class X {}; int main() { /* comment */ return 0; }"));
  CommentVerifier Verifier = Visitor.GetVerifier();
  Verifier.Match("/* comment */", 1, 26);
}

TEST(CommentHandlerTest, BasicTest3) {
  CommentHandlerVisitor Visitor;
  EXPECT_TRUE(Visitor.runOver(
        "class X {}; // comment 1\n"
        "int main() {\n"
        "  // comment 2\n"
        "  return 0;\n"
        "}"));
  CommentVerifier Verifier = Visitor.GetVerifier();
  Verifier.Match("// comment 1", 1, 13);
  Verifier.Match("// comment 2", 3, 3);
}

TEST(CommentHandlerTest, IfBlock1) {
  CommentHandlerVisitor Visitor;
  EXPECT_TRUE(Visitor.runOver(
        "#if 0\n"
        "// ignored comment\n"
        "#endif\n"
        "// visible comment\n"));
  CommentVerifier Verifier = Visitor.GetVerifier();
  Verifier.Match("// visible comment", 4, 1);
}

TEST(CommentHandlerTest, IfBlock2) {
  CommentHandlerVisitor Visitor;
  EXPECT_TRUE(Visitor.runOver(
        "#define TEST        // visible_1\n"
        "#ifndef TEST        // visible_2\n"
        "                    // ignored_3\n"
        "# ifdef UNDEFINED   // ignored_4\n"
        "# endif             // ignored_5\n"
        "#elif defined(TEST) // visible_6\n"
        "# if 1              // visible_7\n"
        "                    // visible_8\n"
        "# else              // visible_9\n"
        "                    // ignored_10\n"
        "#  ifndef TEST      // ignored_11\n"
        "#  endif            // ignored_12\n"
        "# endif             // visible_13\n"
        "#endif              // visible_14\n"));

  CommentVerifier Verifier = Visitor.GetVerifier();
  Verifier.Match("// visible_1", 1, 21);
  Verifier.Match("// visible_2", 2, 21);
  Verifier.Match("// visible_6", 6, 21);
  Verifier.Match("// visible_7", 7, 21);
  Verifier.Match("// visible_8", 8, 21);
  Verifier.Match("// visible_9", 9, 21);
  Verifier.Match("// visible_13", 13, 21);
  Verifier.Match("// visible_14", 14, 21);
}

TEST(CommentHandlerTest, IfBlock3) {
  const char *Source =
        "/* commented out ...\n"
        "#if 0\n"
        "// enclosed\n"
        "#endif */";

  CommentHandlerVisitor Visitor;
  EXPECT_TRUE(Visitor.runOver(Source));
  CommentVerifier Verifier = Visitor.GetVerifier();
  Verifier.Match(Source, 1, 1);
}

TEST(CommentHandlerTest, PPDirectives) {
  CommentHandlerVisitor Visitor;
  EXPECT_TRUE(Visitor.runOver(
        "#warning Y   // ignored_1\n" // #warning takes whole line as message
        "#undef MACRO // visible_2\n"
        "#line 1      // visible_3\n"));

  CommentVerifier Verifier = Visitor.GetVerifier();
  Verifier.Match("// visible_2", 2, 14);
  Verifier.Match("// visible_3", 3, 14);
}

} // end namespace clang
