// 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());

  canonical_rcfile_paths_.push_back(canonical_filename);
  // Keep a pointer to the canonical_filename string in canonical_rcfile_paths_
  // for the RcOptions.
  string* filename_ptr = &canonical_rcfile_paths_.back();

  // 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({filename_ptr, *words_it});
      }
    }
  }

  return ParseError::NONE;
}

}  // namespace blaze
