// Copyright 2017-2020 The Verible Authors.
//
// 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.

#include "verilog/analysis/verilog_project.h"

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

#include "absl/status/status.h"
#include "absl/strings/ascii.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/str_join.h"
#include "absl/strings/string_view.h"
#include "absl/time/time.h"
#include "absl/types/optional.h"
#include "common/text/text_structure.h"
#include "common/util/file_util.h"
#include "common/util/logging.h"
#include "verilog/analysis/verilog_analyzer.h"

namespace verilog {

// All files we process with the verilog project, essentially applications that
// build a symbol table (project-tool, kythe-indexer) only benefit from
// processing the same sequence of tokens a synthesis tool sees.
static constexpr verilog::VerilogPreprocess::Config kPreprocessConfig{
    .filter_branches = true,
};

VerilogSourceFile::VerilogSourceFile(absl::string_view referenced_path,
                                     const absl::Status& status)
    : referenced_path_(referenced_path), status_(status) {}

absl::Status VerilogSourceFile::Open() {
  // Don't re-open.  analyzed_structure_ should be set/written once only.
  if (state_ != State::kInitialized) return status_;

  // Load file contents.
  auto content_status = verible::file::GetContentAsMemBlock(ResolvedPath());
  status_ = content_status.status();
  if (!status_.ok()) return status_;

  content_ = std::move(*content_status);
  state_ = State::kOpened;

  return status_;  // status_ is Ok here.
}

absl::string_view VerilogSourceFile::GetContent() const {
  return content_ ? content_->AsStringView() : "";
}

absl::Status VerilogSourceFile::Parse() {
  // Parsed state is cached.
  if (state_ == State::kParsed) return status_;

  // Open file and load contents if not already done.
  status_ = Open();
  if (!status_.ok()) return status_;

  // Lex, parse, populate underlying TextStructureView.
  analyzed_structure_ = std::make_unique<VerilogAnalyzer>(
      content_, ResolvedPath(), kPreprocessConfig);

  const absl::Time analyze_start = absl::Now();
  status_ = analyzed_structure_->Analyze();
  LOG(INFO) << "Analyzed " << ResolvedPath() << " in "
            << absl::ToInt64Milliseconds(absl::Now() - analyze_start) << "ms";
  state_ = State::kParsed;
  return status_;
}

const verible::TextStructureView* VerilogSourceFile::GetTextStructure() const {
  if (analyzed_structure_ == nullptr) return nullptr;
  return &analyzed_structure_->Data();
}

std::vector<std::string> VerilogSourceFile::ErrorMessages() const {
  std::vector<std::string> result;
  if (!analyzed_structure_) return result;
  result = analyzed_structure_->LinterTokenErrorMessages(false);
  return result;
}

std::ostream& operator<<(std::ostream& stream,
                         const VerilogSourceFile& source) {
  stream << "referenced path: " << source.ReferencedPath() << std::endl;
  stream << "resolved path: " << source.ResolvedPath() << std::endl;
  stream << "corpus: " << source.Corpus() << std::endl;
  const auto status = source.Status();
  stream << "status: " << (status.ok() ? "ok" : status.message()) << std::endl;
  const auto content = source.GetContent();
  stream << "have content? " << (!content.empty() ? "yes" : "no") << std::endl;
  const auto* text_structure = source.GetTextStructure();
  stream << "have text structure? " << (text_structure ? "yes" : "no")
         << std::endl;
  return stream;
}

absl::Status InMemoryVerilogSourceFile::Open() {
  state_ = State::kOpened;
  status_ = absl::OkStatus();
  return status_;
}

absl::Status ParsedVerilogSourceFile::Open() {
  state_ = State::kOpened;
  status_ = absl::OkStatus();
  return status_;
}

absl::Status ParsedVerilogSourceFile::Parse() {
  state_ = State::kParsed;
  status_ = absl::OkStatus();
  return status_;
}

const verible::TextStructureView* ParsedVerilogSourceFile::GetTextStructure()
    const {
  return text_structure_;
}

absl::StatusOr<VerilogSourceFile*> VerilogProject::OpenFile(
    absl::string_view referenced_filename, absl::string_view resolved_filename,
    absl::string_view corpus) {
  const auto inserted = files_.emplace(
      referenced_filename, std::make_unique<VerilogSourceFile>(
                               referenced_filename, resolved_filename, corpus));
  CHECK(inserted.second);  // otherwise, would have already returned above
  const auto file_iter = inserted.first;
  VerilogSourceFile& file(*file_iter->second);

  // Read the file's contents.
  const absl::Status status = file.Open();
  if (!status.ok()) return status;

  // NOTE: string view maps don't support removal operation. The following block
  // is valid only if files won't be removed from the project.
  if (populate_string_maps_) {
    const absl::string_view contents(file.GetContent());

    // Register the file's contents range in string_view_map_.
    string_view_map_.must_emplace(contents);

    // Map the start of the file's contents to its corresponding owner
    // VerilogSourceFile.
    const auto map_inserted =
        buffer_to_analyzer_map_.emplace(contents.begin(), file_iter);
    CHECK(map_inserted.second);
  }

  return &file;
}

bool VerilogProject::RemoveRegisteredFile(
    absl::string_view referenced_filename) {
  CHECK(!populate_string_maps_)
      << "Removing of files added to string maps is not supported! Disable "
         "populating string maps.";
  if (files_.erase(std::string(referenced_filename)) == 1) {
    LOG(INFO) << "Removed " << referenced_filename << " from the project.";
    return true;
  }
  for (const auto& include_path : include_paths_) {
    const std::string resolved_filename =
        verible::file::JoinPath(include_path, referenced_filename);
    if (files_.erase(resolved_filename) == 1) {
      LOG(INFO) << "Removed " << resolved_filename << " from the project.";
      return true;
    }
  }
  return false;
}

VerilogSourceFile* VerilogProject::LookupRegisteredFileInternal(
    absl::string_view referenced_filename) const {
  const auto opened_file = FindOpenedFile(referenced_filename);
  if (opened_file) {
    if (!opened_file->ok()) {
      return nullptr;
    }
    return opened_file->value();
  }

  // Check if this is already opened include file
  for (const auto& include_path : include_paths_) {
    const std::string resolved_filename =
        verible::file::JoinPath(include_path, referenced_filename);
    const auto opened_file = FindOpenedFile(resolved_filename);
    if (opened_file) {
      return opened_file->ok() ? opened_file->value() : nullptr;
    }
  }
  return nullptr;
}

absl::optional<absl::StatusOr<VerilogSourceFile*>>
VerilogProject::FindOpenedFile(absl::string_view filename) const {
  const auto found = files_.find(filename);
  if (found != files_.end()) {
    const auto status = found->second->Status();
    if (!status.ok()) return status;
    return found->second.get();
  }
  return absl::nullopt;
}

absl::StatusOr<VerilogSourceFile*> VerilogProject::OpenTranslationUnit(
    absl::string_view referenced_filename) {
  // Check for a pre-existing entry to avoid duplicate files.
  {
    const auto opened_file = FindOpenedFile(referenced_filename);
    if (opened_file) {
      return *opened_file;
    }
  }

  // Locate the file among the base paths.
  const std::string resolved_filename =
      verible::file::JoinPath(TranslationUnitRoot(), referenced_filename);
  // Check if this is already opened file
  {
    const auto opened_file = FindOpenedFile(resolved_filename);
    if (opened_file) {
      return *opened_file;
    }
  }

  return OpenFile(referenced_filename, resolved_filename, Corpus());
}

absl::Status VerilogProject::IncludeFileNotFoundError(
    absl::string_view referenced_filename) const {
  return absl::NotFoundError(absl::StrCat(
      "Unable to find '", referenced_filename,
      "' among the included paths: ", absl::StrJoin(include_paths_, ", ")));
}

absl::StatusOr<VerilogSourceFile*> VerilogProject::OpenIncludedFile(
    absl::string_view referenced_filename) {
  VLOG(1) << __FUNCTION__ << ", referenced: " << referenced_filename;
  // Check for a pre-existing entry to avoid duplicate files.
  {
    const auto opened_file = FindOpenedFile(referenced_filename);
    if (opened_file) {
      return *opened_file;
    }
  }

  // Check if this is already opened include file
  for (const auto& include_path : include_paths_) {
    const std::string resolved_filename =
        verible::file::JoinPath(include_path, referenced_filename);
    const auto opened_file = FindOpenedFile(resolved_filename);
    if (opened_file) {
      return *opened_file;
    }
  }

  // Locate the file among the base paths.
  for (const auto& include_path : include_paths_) {
    const std::string resolved_filename =
        verible::file::JoinPath(include_path, referenced_filename);
    if (verible::file::FileExists(resolved_filename).ok()) {
      VLOG(2) << "File '" << resolved_filename << "' exists. Resolved from '"
              << referenced_filename << "'";
      return OpenFile(referenced_filename, resolved_filename, Corpus());
    }
    VLOG(2) << "Checked for file'" << resolved_filename
            << "', but not found. Resolved from '" << referenced_filename
            << "'";
  }

  // Not found in any path.  Cache this status.
  const auto inserted = files_.emplace(
      referenced_filename,
      std::make_unique<VerilogSourceFile>(
          referenced_filename, IncludeFileNotFoundError(referenced_filename)));
  CHECK(inserted.second) << "Not-found file should have been recorded as such.";
  return inserted.first->second->Status();
}

void VerilogProject::AddVirtualFile(absl::string_view resolved_filename,
                                    absl::string_view content) {
  const auto inserted = files_.emplace(
      resolved_filename,
      std::make_unique<InMemoryVerilogSourceFile>(
          resolved_filename, std::make_shared<verible::StringMemBlock>(content),
          /*corpus=*/""));
  CHECK(inserted.second);
}

const VerilogSourceFile* VerilogProject::LookupFileOrigin(
    absl::string_view content_substring) const {
  CHECK(populate_string_maps_)
      << "Populating string maps must be enabled for LookupFileOrigin!";
  // Look for corresponding source text (superstring) buffer start.
  const auto found_superstring = string_view_map_.find(content_substring);
  if (found_superstring == string_view_map_.end()) return nullptr;
  const absl::string_view::const_iterator buffer_start =
      found_superstring->first;

  // Reverse-lookup originating file based on buffer start.
  const auto found_file = buffer_to_analyzer_map_.find(buffer_start);
  if (found_file == buffer_to_analyzer_map_.end()) return nullptr;

  const VerilogSourceFile* file = found_file->second->second.get();
  return file;
}

}  // namespace verilog
