// Copyright 2015 Google Inc. 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.

// +build ignore

#include "rule.h"

#include "expr.h"
#include "log.h"
#include "parser.h"
#include "stringprintf.h"
#include "strutil.h"
#include "symtab.h"

namespace {

static void ParseInputs(Rule* r, StringPiece s) {
  bool is_order_only = false;
  for (StringPiece input : WordScanner(s)) {
    if (input == "|") {
      is_order_only = true;
      continue;
    }
    Symbol input_sym = Intern(TrimLeadingCurdir(input));
    if (is_order_only) {
      r->order_only_inputs.push_back(input_sym);
    } else {
      r->inputs.push_back(input_sym);
    }
  }
}

bool IsPatternRule(StringPiece s) {
  return s.find('%') != string::npos;
}

}  // namespace

Rule::Rule()
    : is_double_colon(false),
      is_suffix_rule(false),
      cmd_lineno(0) {
}

void ParseRule(Loc& loc, StringPiece line, char term,
               Rule** out_rule, RuleVarAssignment* rule_var) {
  size_t index = line.find(':');
  if (index == string::npos) {
    ERROR("%s:%d: *** missing separator.", LOCF(loc));
  }

  StringPiece first = line.substr(0, index);
  vector<Symbol> outputs;
  for (StringPiece tok : WordScanner(first)) {
    outputs.push_back(Intern(TrimLeadingCurdir(tok)));
  }

  const bool is_first_pattern = (
      !outputs.empty() && IsPatternRule(outputs[0].str()));
  for (size_t i = 1; i < outputs.size(); i++) {
    if (IsPatternRule(outputs[i].str()) != is_first_pattern) {
      ERROR("%s:%d: *** mixed implicit and normal rules: deprecated syntax",
            LOCF(loc));
    }
  }

  bool is_double_colon = false;
  index++;
  if (line.get(index) == ':') {
    is_double_colon = true;
    index++;
  }

  StringPiece rest = line.substr(index);
  size_t term_index = rest.find_first_of("=;");
  if ((term_index != string::npos && rest[term_index] == '=') ||
      (term_index == string::npos && term == '=')) {
    if (term_index == string::npos)
      term_index = rest.size();
    rule_var->outputs.swap(outputs);
    ParseAssignStatement(rest, term_index,
                         &rule_var->lhs, &rule_var->rhs, &rule_var->op);
    *out_rule = NULL;
    return;
  }

  Rule* rule = new Rule();
  *out_rule = rule;
  rule->loc = loc;
  rule->is_double_colon = is_double_colon;
  if (is_first_pattern) {
    rule->output_patterns.swap(outputs);
  } else {
    rule->outputs.swap(outputs);
  }
  if (term_index != string::npos && term != ';') {
    CHECK(rest[term_index] == ';');
    // TODO: Maybe better to avoid Intern here?
    rule->cmds.push_back(
        NewLiteral(Intern(TrimLeftSpace(rest.substr(term_index + 1))).str()));
    rest = rest.substr(0, term_index);
  }

  index = rest.find(':');
  if (index == string::npos) {
    ParseInputs(rule, rest);
    return;
  }

  if (is_first_pattern) {
    ERROR("%s:%d: *** mixed implicit and normal rules: deprecated syntax",
          LOCF(loc));
  }

  StringPiece second = rest.substr(0, index);
  StringPiece third = rest.substr(index+1);

  for (StringPiece tok : WordScanner(second)) {
    tok = TrimLeadingCurdir(tok);
    for (Symbol output : rule->outputs) {
      if (!Pattern(tok).Match(output.str())) {
        WARN("%s:%d: target `%s' doesn't match the target pattern",
             LOCF(loc), output.c_str());
      }
    }

    rule->output_patterns.push_back(Intern(tok));
  }

  if (rule->output_patterns.empty()) {
    ERROR("%s:%d: *** missing target pattern.", LOCF(loc));
  }
  if (rule->output_patterns.size() > 1) {
    ERROR("%s:%d: *** multiple target patterns.", LOCF(loc));
  }
  if (!IsPatternRule(rule->output_patterns[0].str())) {
    ERROR("%s:%d: *** target pattern contains no '%%'.", LOCF(loc));
  }
  ParseInputs(rule, third);
}

string Rule::DebugString() const {
  vector<string> v;
  v.push_back(StringPrintf("outputs=[%s]", JoinSymbols(outputs, ",").c_str()));
  v.push_back(StringPrintf("inputs=[%s]", JoinSymbols(inputs, ",").c_str()));
  if (!order_only_inputs.empty()) {
    v.push_back(StringPrintf("order_only_inputs=[%s]",
                             JoinSymbols(order_only_inputs, ",").c_str()));
  }
  if (!output_patterns.empty()) {
    v.push_back(StringPrintf("output_patterns=[%s]",
                             JoinSymbols(output_patterns, ",").c_str()));
  }
  if (is_double_colon)
    v.push_back("is_double_colon");
  if (is_suffix_rule)
    v.push_back("is_suffix_rule");
  if (!cmds.empty()) {
    v.push_back(StringPrintf("cmds=[%s]", JoinValues(cmds, ",").c_str()));
  }
  return JoinStrings(v, " ");
}
