// Copyright 2018 The Bazel Authors. All rights reserved.
//
// 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 "src/main/cpp/rc_file.h"

#include <algorithm>
#include <utility>

#include "src/main/cpp/blaze_util.h"
#include "src/main/cpp/blaze_util_platform.h"
#include "src/main/cpp/util/file.h"
#include "src/main/cpp/util/logging.h"
#include "src/main/cpp/util/strings.h"
#include "src/main/cpp/workspace_layout.h"

namespace blaze {

using std::deque;
using std::string;
using std::vector;

static constexpr const char* kCommandImport = "import";
static constexpr const char* kCommandTryImport = "try-import";

RcFile::RcFile(string filename, const WorkspaceLayout* workspace_layout,
               string workspace)
    : filename_(std::move(filename)),
      workspace_layout_(workspace_layout),
      workspace_(std::move(workspace)) {}

/*static*/ std::unique_ptr<RcFile> RcFile::Parse(
    std::string filename, const WorkspaceLayout* workspace_layout,
    std::string workspace, ParseError* error, std::string* error_text) {
  std::unique_ptr<RcFile> rcfile(new RcFile(
      std::move(filename), workspace_layout, std::move(workspace)));
  deque<string> initial_import_stack = {rcfile->filename_};
  *error = rcfile->ParseFile(
      rcfile->filename_, &initial_import_stack, error_text);
  return (*error == ParseError::NONE) ? std::move(rcfile) : nullptr;
}

RcFile::ParseError RcFile::ParseFile(const string& filename,
                                     deque<string>* import_stack,
                                     string* error_text) {
  BAZEL_LOG(INFO) << "Parsing the RcFile " << filename;
  string contents;
  if (!blaze_util::ReadFile(filename, &contents)) {
    blaze_util::StringPrintf(error_text,
        "Unexpected error reading .blazerc file '%s'", filename.c_str());
    return ParseError::UNREADABLE_FILE;
  }
  const std::string canonical_filename =
      blaze_util::MakeCanonical(filename.c_str());

  int rcfile_index = canonical_rcfile_paths_.size();
  canonical_rcfile_paths_.push_back(canonical_filename);

  // A '\' at the end of a line continues the line.
  blaze_util::Replace("\\\r\n", "", &contents);
  blaze_util::Replace("\\\n", "", &contents);

  vector<string> lines = blaze_util::Split(contents, '\n');
  for (string& line : lines) {
    blaze_util::StripWhitespace(&line);

    // Check for an empty line.
    if (line.empty()) {
      continue;
    }

    vector<string> words;

    // This will treat "#" as a comment, and properly
    // quote single and double quotes, and treat '\'
    // as an escape character.
    // TODO(bazel-team): This function silently ignores
    // dangling backslash escapes and missing end-quotes.
    blaze_util::Tokenize(line, '#', &words);

    if (words.empty()) {
      // Could happen if line starts with "#"
      continue;
    }

    string command = words[0];

    if (command == kCommandImport || command == kCommandTryImport) {
      if (words.size() != 2 ||
          (words[1].compare(0, workspace_layout_->WorkspacePrefixLength,
                            workspace_layout_->WorkspacePrefix) == 0 &&
           !workspace_layout_->WorkspaceRelativizeRcFilePath(workspace_,
                                                             &words[1]))) {
        blaze_util::StringPrintf(
            error_text,
            "Invalid import declaration in .blazerc file '%s': '%s'"
            " (are you in your source checkout/WORKSPACE?)",
            canonical_filename.c_str(), line.c_str());
        return ParseError::INVALID_FORMAT;
      }
      if (std::find(import_stack->begin(), import_stack->end(), words[1]) !=
          import_stack->end()) {
        string loop;
        for (const string& imported_rc : *import_stack) {
          loop += "  " + imported_rc + "\n";
        }
        loop += "  " + words[1] + "\n";  // Include the loop.
        blaze_util::StringPrintf(error_text,
            "Import loop detected:\n%s", loop.c_str());
        return ParseError::IMPORT_LOOP;
      }

      import_stack->push_back(words[1]);
      ParseError parse_error = ParseFile(words[1], import_stack, error_text);
      if (parse_error != ParseError::NONE) {
        if (parse_error == ParseError::UNREADABLE_FILE &&
            command == kCommandTryImport) {
          // For try-import, we ignore it if we couldn't find a file.
          BAZEL_LOG(INFO) << "Skipped optional import of " << words[1]
                          << ", the specified rc file either does not exist or "
                             "is not readable.";
          *error_text = "";
        } else {
          // Files that are there but are malformed or introduce a loop are
          // still a problem, though, so perpetuate those errors as we would
          // for a normal import statement.
          return parse_error;
        }
      }
      import_stack->pop_back();
    } else {
      auto words_it = words.begin();
      words_it++;  // Advance past command.
      for (; words_it != words.end(); words_it++) {
        options_[command].push_back({*words_it, rcfile_index});
      }
    }
  }

  return ParseError::NONE;
}

}  // namespace blaze
