/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
   file LICENSE.rst or https://cmake.org/licensing for details.  */
#define cmListFileCache_cxx
#include "cmListFileCache.h"

#include <memory>
#include <ostream>
#include <utility>

#ifdef _WIN32
#  include <cmsys/Encoding.hxx>
#endif

#include <cm/string_view>

#include "cmList.h"
#include "cmListFileLexer.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmake.h"

namespace {

enum class NestingStateEnum
{
  If,
  Else,
  While,
  Foreach,
  Function,
  Macro,
  Block
};

struct NestingState
{
  NestingStateEnum State;
  cmListFileContext Context;
};

bool TopIs(std::vector<NestingState>& stack, NestingStateEnum state)
{
  return !stack.empty() && stack.back().State == state;
}

class cmListFileParser
{
public:
  cmListFileParser(cmListFile* lf, cmListFileBacktrace lfbt,
                   cmMakefile const* mf, std::string const& filename);
  cmListFileParser(cmListFileParser const&) = delete;
  cmListFileParser& operator=(cmListFileParser const&) = delete;

  bool ParseFile();
  bool ParseString(cm::string_view str);

private:
  bool Parse();
  bool ParseFunction(cm::string_view name, long line);
  bool AddArgument(cmListFileLexer_Token* token,
                   cmListFileArgument::Delimiter delim);
  void IssueFileOpenError(std::string const& text) const;
  void IssueError(std::string const& text) const;

  cm::optional<cmListFileContext> CheckNesting() const;

  enum
  {
    SeparationOkay,
    SeparationWarning,
    SeparationError
  } Separation;

  cmListFile* ListFile;
  cmListFileBacktrace Backtrace;
  cmMakefile const* Makefile;
  std::string const& FileName;
  std::unique_ptr<cmListFileLexer, void (*)(cmListFileLexer*)> Lexer;
  std::string FunctionName;
  long FunctionLine;
  long FunctionLineEnd;
  std::vector<cmListFileArgument> FunctionArguments;
};

cmListFileParser::cmListFileParser(cmListFile* lf, cmListFileBacktrace lfbt,
                                   cmMakefile const* mf,
                                   std::string const& filename)
  : ListFile(lf)
  , Backtrace(std::move(lfbt))
  , Makefile(mf)
  , FileName(filename)
  , Lexer(cmListFileLexer_New(), cmListFileLexer_Delete)
{
}

void cmListFileParser::IssueFileOpenError(std::string const& text) const
{
  if (this->Makefile) {
    this->Makefile->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR,
                                                     text, this->Backtrace);
  }
}

void cmListFileParser::IssueError(std::string const& text) const
{
  if (this->Makefile) {
    cmListFileContext lfc;
    lfc.FilePath = this->FileName;
    lfc.Line = cmListFileLexer_GetCurrentLine(this->Lexer.get());
    cmListFileBacktrace lfbt = this->Backtrace;
    lfbt = lfbt.Push(lfc);
    this->Makefile->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR,
                                                     text, lfbt);
  }
  cmSystemTools::SetFatalErrorOccurred();
}

bool cmListFileParser::ParseFile()
{
  std::string const* filename = &this->FileName;

#ifdef _WIN32
  std::string expandedFileName = cmsys::Encoding::ToNarrow(
    cmSystemTools::ConvertToWindowsExtendedPath(*filename));
  filename = &expandedFileName;
#endif

  // Open the file.
  cmListFileLexer_BOM bom;
  if (!cmListFileLexer_SetFileName(this->Lexer.get(), filename->c_str(),
                                   &bom)) {
    this->IssueFileOpenError("cmListFileCache: error can not open file.");
    return false;
  }

  // Verify the Byte-Order-Mark, if any.
  if (bom != cmListFileLexer_BOM_None && bom != cmListFileLexer_BOM_UTF8) {
    cmListFileLexer_SetFileName(this->Lexer.get(), nullptr, nullptr);
    this->IssueFileOpenError(
      "File starts with a Byte-Order-Mark that is not UTF-8.");
    return false;
  }

  return this->Parse();
}

bool cmListFileParser::ParseString(cm::string_view str)
{
  if (!cmListFileLexer_SetString(this->Lexer.get(), str.data(),
                                 str.length())) {
    this->IssueFileOpenError("cmListFileCache: cannot allocate buffer.");
    return false;
  }

  return this->Parse();
}

bool cmListFileParser::Parse()
{
  // Use a simple recursive-descent parser to process the token
  // stream.
  bool haveNewline = true;
  while (cmListFileLexer_Token* token =
           cmListFileLexer_Scan(this->Lexer.get())) {
    if (token->type == cmListFileLexer_Token_Space) {
    } else if (token->type == cmListFileLexer_Token_Newline) {
      haveNewline = true;
    } else if (token->type == cmListFileLexer_Token_CommentBracket) {
      haveNewline = false;
    } else if (token->type == cmListFileLexer_Token_Identifier) {
      if (haveNewline) {
        haveNewline = false;
        if (this->ParseFunction(cm::string_view(token->text, token->length),
                                token->line)) {
          this->ListFile->Functions.emplace_back(
            std::move(this->FunctionName), this->FunctionLine,
            this->FunctionLineEnd, std::move(this->FunctionArguments));
        } else {
          return false;
        }
      } else {
        auto error = cmStrCat(
          "Parse error.  Expected a newline, got ",
          cmListFileLexer_GetTypeAsString(this->Lexer.get(), token->type),
          " with text \"", cm::string_view(token->text, token->length), "\".");
        this->IssueError(error);
        return false;
      }
    } else {
      auto error = cmStrCat(
        "Parse error.  Expected a command name, got ",
        cmListFileLexer_GetTypeAsString(this->Lexer.get(), token->type),
        " with text \"", cm::string_view(token->text, token->length), "\".");
      this->IssueError(error);
      return false;
    }
  }

  // Check if all functions are nested properly.
  if (auto badNesting = this->CheckNesting()) {
    if (this->Makefile) {
      this->Makefile->GetCMakeInstance()->IssueMessage(
        MessageType::FATAL_ERROR,
        "Flow control statements are not properly nested.",
        this->Backtrace.Push(*badNesting));
    }
    cmSystemTools::SetFatalErrorOccurred();
    return false;
  }

  return true;
}

bool cmListFileParser::ParseFunction(cm::string_view name, long line)
{
  // Ininitialize a new function call.
  this->FunctionName.assign(name.data(), name.size());
  this->FunctionLine = line;

  // Command name has already been parsed.  Read the left paren.
  cmListFileLexer_Token* token;
  while ((token = cmListFileLexer_Scan(this->Lexer.get())) &&
         token->type == cmListFileLexer_Token_Space) {
  }
  if (!token) {
    this->IssueError("Unexpected end of file.\n"
                     "Parse error.  Function missing opening \"(\".");
    return false;
  }
  if (token->type != cmListFileLexer_Token_ParenLeft) {
    auto error = cmStrCat(
      "Parse error.  Expected \"(\", got ",
      cmListFileLexer_GetTypeAsString(this->Lexer.get(), token->type),
      " with text \"", cm::string_view(token->text, token->length), "\".");
    this->IssueError(error);
    return false;
  }

  // Arguments.
  unsigned long parenDepth = 0;
  this->Separation = SeparationOkay;
  while ((token = cmListFileLexer_Scan(this->Lexer.get()))) {
    if (token->type == cmListFileLexer_Token_Space ||
        token->type == cmListFileLexer_Token_Newline) {
      this->Separation = SeparationOkay;
      continue;
    }
    if (token->type == cmListFileLexer_Token_ParenLeft) {
      parenDepth++;
      this->Separation = SeparationOkay;
      if (!this->AddArgument(token, cmListFileArgument::Unquoted)) {
        return false;
      }
    } else if (token->type == cmListFileLexer_Token_ParenRight) {
      if (parenDepth == 0) {
        this->FunctionLineEnd = token->line;
        return true;
      }
      parenDepth--;
      this->Separation = SeparationOkay;
      if (!this->AddArgument(token, cmListFileArgument::Unquoted)) {
        return false;
      }
      this->Separation = SeparationWarning;
    } else if (token->type == cmListFileLexer_Token_Identifier ||
               token->type == cmListFileLexer_Token_ArgumentUnquoted) {
      if (!this->AddArgument(token, cmListFileArgument::Unquoted)) {
        return false;
      }
      this->Separation = SeparationWarning;
    } else if (token->type == cmListFileLexer_Token_ArgumentQuoted) {
      if (!this->AddArgument(token, cmListFileArgument::Quoted)) {
        return false;
      }
      this->Separation = SeparationWarning;
    } else if (token->type == cmListFileLexer_Token_ArgumentBracket) {
      if (!this->AddArgument(token, cmListFileArgument::Bracket)) {
        return false;
      }
      this->Separation = SeparationError;
    } else if (token->type == cmListFileLexer_Token_CommentBracket) {
      this->Separation = SeparationError;
    } else {
      // Error.
      auto error = cmStrCat(
        "Parse error.  Function missing ending \")\".  "
        "Instead found ",
        cmListFileLexer_GetTypeAsString(this->Lexer.get(), token->type),
        " with text \"", cm::string_view(token->text, token->length), "\".");
      this->IssueError(error);
      return false;
    }
  }

  if (this->Makefile) {
    cmListFileContext lfc;
    lfc.FilePath = this->FileName;
    lfc.Line = line;
    cmListFileBacktrace lfbt = this->Backtrace;
    lfbt = lfbt.Push(lfc);
    this->Makefile->GetCMakeInstance()->IssueMessage(
      MessageType::FATAL_ERROR,
      "Parse error.  Function missing ending \")\".  "
      "End of file reached.",
      lfbt);
  }
  return false;
}

bool cmListFileParser::AddArgument(cmListFileLexer_Token* token,
                                   cmListFileArgument::Delimiter delim)
{
  this->FunctionArguments.emplace_back(
    cm::string_view(token->text, token->length), delim, token->line);
  if (this->Separation == SeparationOkay) {
    return true;
  }
  bool isError = (this->Separation == SeparationError ||
                  delim == cmListFileArgument::Bracket);
  cmListFileContext lfc;
  lfc.FilePath = this->FileName;
  lfc.Line = token->line;
  cmListFileBacktrace lfbt = this->Backtrace;
  lfbt = lfbt.Push(lfc);
  auto msg =
    cmStrCat("Syntax ", (isError ? "Error" : "Warning"),
             " in cmake code at column ", token->column,
             "\n"
             "Argument not separated from preceding token by whitespace.");
  if (isError) {
    if (this->Makefile) {
      this->Makefile->GetCMakeInstance()->IssueMessage(
        MessageType::FATAL_ERROR, msg, lfbt);
    }
    return false;
  }
  if (this->Makefile) {
    this->Makefile->IssueMessage(MessageType::AUTHOR_WARNING, msg, lfbt);
  }
  return true;
}

cm::optional<cmListFileContext> cmListFileParser::CheckNesting() const
{
  std::vector<NestingState> stack;

  for (auto const& func : this->ListFile->Functions) {
    auto const& name = func.LowerCaseName();
    if (name == "if") {
      stack.push_back({
        NestingStateEnum::If,
        cmListFileContext::FromListFileFunction(func, this->FileName),
      });
    } else if (name == "elseif") {
      if (!TopIs(stack, NestingStateEnum::If)) {
        return cmListFileContext::FromListFileFunction(func, this->FileName);
      }
      stack.back() = {
        NestingStateEnum::If,
        cmListFileContext::FromListFileFunction(func, this->FileName),
      };
    } else if (name == "else") {
      if (!TopIs(stack, NestingStateEnum::If)) {
        return cmListFileContext::FromListFileFunction(func, this->FileName);
      }
      stack.back() = {
        NestingStateEnum::Else,
        cmListFileContext::FromListFileFunction(func, this->FileName),
      };
    } else if (name == "endif") {
      if (!TopIs(stack, NestingStateEnum::If) &&
          !TopIs(stack, NestingStateEnum::Else)) {
        return cmListFileContext::FromListFileFunction(func, this->FileName);
      }
      stack.pop_back();
    } else if (name == "while") {
      stack.push_back({
        NestingStateEnum::While,
        cmListFileContext::FromListFileFunction(func, this->FileName),
      });
    } else if (name == "endwhile") {
      if (!TopIs(stack, NestingStateEnum::While)) {
        return cmListFileContext::FromListFileFunction(func, this->FileName);
      }
      stack.pop_back();
    } else if (name == "foreach") {
      stack.push_back({
        NestingStateEnum::Foreach,
        cmListFileContext::FromListFileFunction(func, this->FileName),
      });
    } else if (name == "endforeach") {
      if (!TopIs(stack, NestingStateEnum::Foreach)) {
        return cmListFileContext::FromListFileFunction(func, this->FileName);
      }
      stack.pop_back();
    } else if (name == "function") {
      stack.push_back({
        NestingStateEnum::Function,
        cmListFileContext::FromListFileFunction(func, this->FileName),
      });
    } else if (name == "endfunction") {
      if (!TopIs(stack, NestingStateEnum::Function)) {
        return cmListFileContext::FromListFileFunction(func, this->FileName);
      }
      stack.pop_back();
    } else if (name == "macro") {
      stack.push_back({
        NestingStateEnum::Macro,
        cmListFileContext::FromListFileFunction(func, this->FileName),
      });
    } else if (name == "endmacro") {
      if (!TopIs(stack, NestingStateEnum::Macro)) {
        return cmListFileContext::FromListFileFunction(func, this->FileName);
      }
      stack.pop_back();
    } else if (name == "block") {
      stack.push_back({
        NestingStateEnum::Block,
        cmListFileContext::FromListFileFunction(func, this->FileName),
      });
    } else if (name == "endblock") {
      if (!TopIs(stack, NestingStateEnum::Block)) {
        return cmListFileContext::FromListFileFunction(func, this->FileName);
      }
      stack.pop_back();
    }
  }

  if (!stack.empty()) {
    return stack.back().Context;
  }

  return cm::nullopt;
}

} // anonymous namespace

bool cmListFile::ParseFile(std::string const& filename, cmMakefile const* mf,
                           cmListFileBacktrace const& lfbt)
{
  if (!cmSystemTools::FileExists(filename) ||
      cmSystemTools::FileIsDirectory(filename)) {
    return false;
  }

  cmListFileParser parser(this, lfbt, mf, filename);
  return parser.ParseFile();
}

bool cmListFile::ParseString(cm::string_view str,
                             std::string const& virtual_filename,
                             cmMakefile const* mf,
                             cmListFileBacktrace const& lfbt)
{
  cmListFileParser parser(this, lfbt, mf, virtual_filename);
  return parser.ParseString(str);
}

#include "cmConstStack.tcc"
template class cmConstStack<cmListFileContext, cmListFileBacktrace>;

std::ostream& operator<<(std::ostream& os, cmListFileContext const& lfc)
{
  os << lfc.FilePath;
  if (lfc.Line > 0) {
    os << ':' << lfc.Line;
    if (!lfc.Name.empty()) {
      os << " (" << lfc.Name << ')';
    }
  } else if (lfc.Line == cmListFileContext::DeferPlaceholderLine) {
    os << ":DEFERRED";
  }
  return os;
}

bool operator<(cmListFileContext const& lhs, cmListFileContext const& rhs)
{
  if (lhs.Line != rhs.Line) {
    return lhs.Line < rhs.Line;
  }
  return lhs.FilePath < rhs.FilePath;
}

bool operator==(cmListFileContext const& lhs, cmListFileContext const& rhs)
{
  return lhs.Line == rhs.Line && lhs.FilePath == rhs.FilePath;
}

bool operator!=(cmListFileContext const& lhs, cmListFileContext const& rhs)
{
  return !(lhs == rhs);
}

std::ostream& operator<<(std::ostream& os, BT<std::string> const& s)
{
  return os << s.Value;
}

std::vector<BT<std::string>> cmExpandListWithBacktrace(
  std::string const& list, cmListFileBacktrace const& bt,
  cmList::EmptyElements emptyArgs)
{
  std::vector<BT<std::string>> result;
  cmList tmp{ list, emptyArgs };
  result.reserve(tmp.size());
  for (std::string& i : tmp) {
    result.emplace_back(std::move(i), bt);
  }
  return result;
}
