//===- unittest/Tooling/CommentHandlerTest.cpp -----------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#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, public CommentHandler {
public:
  CommentHandlerVisitor() : PP(nullptr), Verified(false) {}

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

  bool HandleComment(Preprocessor &PP, SourceRange Loc) override {
    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:
  std::unique_ptr<ASTFrontendAction> CreateTestAction() override {
    return std::make_unique<CommentHandlerAction>(this);
  }

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

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

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

    void EndSourceFileAction() override {
      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(CommentVerifier &&C) : Current(C.Current), End(C.End), PP(C.PP) {
    C.Current = C.End;
  }

  ~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
