/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
   file Copyright.txt or https://cmake.org/licensing for details.  */
#include "cmGccDepfileLexerHelper.h"

#include <algorithm>
#include <cstdio>
#include <string>
#include <vector>

#include "cmGccDepfileReaderTypes.h"

#include "LexerParser/cmGccDepfileLexer.h"

#ifdef _WIN32
#  include <cctype>

#  include "cmsys/Encoding.h"
#endif

bool cmGccDepfileLexerHelper::readFile(const char* filePath)
{
#ifdef _WIN32
  wchar_t* wpath = cmsysEncoding_DupToWide(filePath);
  FILE* file = _wfopen(wpath, L"rb");
  free(wpath);
#else
  FILE* file = fopen(filePath, "r");
#endif
  if (!file) {
    return false;
  }
  this->newEntry();
  yyscan_t scanner;
  cmGccDepfile_yylex_init(&scanner);
  cmGccDepfile_yyset_extra(this, scanner);
  cmGccDepfile_yyrestart(file, scanner);
  cmGccDepfile_yylex(scanner);
  cmGccDepfile_yylex_destroy(scanner);
  this->sanitizeContent();
  fclose(file);
  return this->HelperState != State::Failed;
}

void cmGccDepfileLexerHelper::newEntry()
{
  if (this->HelperState == State::Rule && !this->Content.empty()) {
    if (!this->Content.back().rules.empty() &&
        !this->Content.back().rules.back().empty()) {
      this->HelperState = State::Failed;
    }
    return;
  }
  this->HelperState = State::Rule;
  this->Content.emplace_back();
  this->newRule();
}

void cmGccDepfileLexerHelper::newRule()
{
  auto& entry = this->Content.back();
  if (entry.rules.empty() || !entry.rules.back().empty()) {
    entry.rules.emplace_back();
  }
}

void cmGccDepfileLexerHelper::newDependency()
{
  if (this->HelperState == State::Failed) {
    return;
  }
  this->HelperState = State::Dependency;
  auto& entry = this->Content.back();
  if (entry.paths.empty() || !entry.paths.back().empty()) {
    entry.paths.emplace_back();
  }
}

void cmGccDepfileLexerHelper::newRuleOrDependency()
{
  if (this->HelperState == State::Rule) {
    this->newRule();
  } else if (this->HelperState == State::Dependency) {
    this->newDependency();
  }
}

void cmGccDepfileLexerHelper::addToCurrentPath(const char* s)
{
  if (this->Content.empty()) {
    return;
  }
  cmGccStyleDependency* dep = &this->Content.back();
  std::string* dst = nullptr;
  switch (this->HelperState) {
    case State::Rule: {
      if (dep->rules.empty()) {
        return;
      }
      dst = &dep->rules.back();
    } break;
    case State::Dependency: {
      if (dep->paths.empty()) {
        return;
      }
      dst = &dep->paths.back();
    } break;
    case State::Failed:
      return;
  }
  dst->append(s);
}

void cmGccDepfileLexerHelper::sanitizeContent()
{
  for (auto it = this->Content.begin(); it != this->Content.end();) {
    // remove duplicate path entries
    std::sort(it->paths.begin(), it->paths.end());
    auto last = std::unique(it->paths.begin(), it->paths.end());
    it->paths.erase(last, it->paths.end());

    // Remove empty paths and normalize windows paths
    for (auto pit = it->paths.begin(); pit != it->paths.end();) {
      if (pit->empty()) {
        pit = it->paths.erase(pit);
      } else {
#if defined(_WIN32)
        // Unescape the colon following the drive letter.
        // Some versions of GNU compilers can escape this character.
        // c\:\path must be transformed to c:\path
        if (pit->size() >= 3 && std::toupper((*pit)[0]) >= 'A' &&
            std::toupper((*pit)[0]) <= 'Z' && (*pit)[1] == '\\' &&
            (*pit)[2] == ':') {
          pit->erase(1, 1);
        }
#endif
        ++pit;
      }
    }
    // Remove empty rules
    for (auto rit = it->rules.begin(); rit != it->rules.end();) {
      if (rit->empty()) {
        rit = it->rules.erase(rit);
      } else {
        ++rit;
      }
    }
    // Remove the entry if rules are empty
    if (it->rules.empty()) {
      it = this->Content.erase(it);
    } else {
      ++it;
    }
  }
}
