// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "tools/gn/substitution_pattern.h"

#include <stddef.h>

#include "base/strings/string_number_conversions.h"
#include "tools/gn/build_settings.h"
#include "tools/gn/err.h"
#include "tools/gn/filesystem_utils.h"
#include "tools/gn/value.h"

SubstitutionPattern::Subrange::Subrange() : type(SUBSTITUTION_LITERAL) {}

SubstitutionPattern::Subrange::Subrange(SubstitutionType t,
                                        const std::string& l)
    : type(t), literal(l) {}

SubstitutionPattern::Subrange::~Subrange() = default;

SubstitutionPattern::SubstitutionPattern() : origin_(nullptr) {}

SubstitutionPattern::SubstitutionPattern(const SubstitutionPattern& other) =
    default;

SubstitutionPattern::~SubstitutionPattern() = default;

bool SubstitutionPattern::Parse(const Value& value, Err* err) {
  if (!value.VerifyTypeIs(Value::STRING, err))
    return false;
  return Parse(value.string_value(), value.origin(), err);
}

bool SubstitutionPattern::Parse(const std::string& str,
                                const ParseNode* origin,
                                Err* err) {
  DCHECK(ranges_.empty());  // Should only be called once.

  size_t cur = 0;
  while (true) {
    size_t next = str.find("{{", cur);

    // Pick up everything from the previous spot to here as a literal.
    if (next == std::string::npos) {
      if (cur != str.size())
        ranges_.push_back(Subrange(SUBSTITUTION_LITERAL, str.substr(cur)));
      break;
    } else if (next > cur) {
      ranges_.push_back(
          Subrange(SUBSTITUTION_LITERAL, str.substr(cur, next - cur)));
    }

    // Find which specific pattern this corresponds to.
    bool found_match = false;
    for (size_t i = SUBSTITUTION_FIRST_PATTERN; i < SUBSTITUTION_NUM_TYPES;
         i++) {
      const char* cur_pattern = kSubstitutionNames[i];
      size_t cur_len = strlen(cur_pattern);
      if (str.compare(next, cur_len, cur_pattern) == 0) {
        ranges_.push_back(Subrange(static_cast<SubstitutionType>(i)));
        cur = next + cur_len;
        found_match = true;
        break;
      }
    }

    // Expect all occurrances of {{ to resolve to a pattern.
    if (!found_match) {
      // Could make this error message more friendly if it comes up a lot. But
      // most people will not be writing substitution patterns and the code
      // to exactly indicate the error location is tricky.
      *err = Err(origin, "Unknown substitution pattern",
                 "Found a {{ at offset " + base::NumberToString(next) +
                     " and did not find a known substitution following it.");
      ranges_.clear();
      return false;
    }
  }

  origin_ = origin;

  // Fill required types vector.
  SubstitutionBits bits;
  FillRequiredTypes(&bits);
  bits.FillVector(&required_types_);
  return true;
}

// static
SubstitutionPattern SubstitutionPattern::MakeForTest(const char* str) {
  Err err;
  SubstitutionPattern pattern;
  CHECK(pattern.Parse(str, nullptr, &err)) << err.message();
  return pattern;
}

std::string SubstitutionPattern::AsString() const {
  std::string result;
  for (const auto& elem : ranges_) {
    if (elem.type == SUBSTITUTION_LITERAL)
      result.append(elem.literal);
    else
      result.append(kSubstitutionNames[elem.type]);
  }
  return result;
}

void SubstitutionPattern::FillRequiredTypes(SubstitutionBits* bits) const {
  for (const auto& elem : ranges_) {
    if (elem.type != SUBSTITUTION_LITERAL)
      bits->used[static_cast<size_t>(elem.type)] = true;
  }
}

bool SubstitutionPattern::IsInOutputDir(const BuildSettings* build_settings,
                                        Err* err) const {
  if (ranges_.empty()) {
    *err = Err(origin_, "This is empty but I was expecting an output file.");
    return false;
  }

  if (ranges_[0].type == SUBSTITUTION_LITERAL) {
    // If the first thing is a literal, it must start with the output dir.
    if (!EnsureStringIsInOutputDir(build_settings->build_dir(),
                                   ranges_[0].literal, origin_, err))
      return false;
  } else {
    // Otherwise, the first subrange must be a pattern that expands to
    // something in the output directory.
    if (!SubstitutionIsInOutputDir(ranges_[0].type)) {
      *err =
          Err(origin_, "File is not inside output directory.",
              "The given file should be in the output directory. Normally you\n"
              "would specify\n\"$target_out_dir/foo\" or "
              "\"{{source_gen_dir}}/foo\".");
      return false;
    }
  }

  return true;
}
