// 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 "stmt.h"

#include "eval.h"
#include "expr.h"
#include "stringprintf.h"
#include "strutil.h"

Stmt::Stmt() {}

Stmt::~Stmt() {}

string RuleStmt::DebugString() const {
  return StringPrintf("RuleStmt(lhs=%s sep=%d rhs=%s loc=%s:%d)",
                      Value::DebugString(lhs).c_str(), sep,
                      Value::DebugString(rhs).c_str(), LOCF(loc()));
}

string AssignStmt::DebugString() const {
  const char* opstr = "???";
  switch (op) {
    case AssignOp::EQ:
      opstr = "EQ";
      break;
    case AssignOp::COLON_EQ:
      opstr = "COLON_EQ";
      break;
    case AssignOp::PLUS_EQ:
      opstr = "PLUS_EQ";
      break;
    case AssignOp::QUESTION_EQ:
      opstr = "QUESTION_EQ";
      break;
  }
  const char* dirstr = "???";
  switch (directive) {
    case AssignDirective::NONE:
      dirstr = "";
      break;
    case AssignDirective::OVERRIDE:
      dirstr = "override";
      break;
    case AssignDirective::EXPORT:
      dirstr = "export";
      break;
  }
  return StringPrintf(
      "AssignStmt(lhs=%s rhs=%s (%s) "
      "opstr=%s dir=%s loc=%s:%d)",
      Value::DebugString(lhs).c_str(), Value::DebugString(rhs).c_str(),
      NoLineBreak(orig_rhs.as_string()).c_str(), opstr, dirstr, LOCF(loc()));
}

Symbol AssignStmt::GetLhsSymbol(Evaluator* ev) const {
  if (!lhs->IsLiteral()) {
    string buf;
    lhs->Eval(ev, &buf);
    return Intern(buf);
  }

  if (!lhs_sym_cache_.IsValid()) {
    lhs_sym_cache_ = Intern(lhs->GetLiteralValueUnsafe());
  }
  return lhs_sym_cache_;
}

string CommandStmt::DebugString() const {
  return StringPrintf("CommandStmt(%s, loc=%s:%d)",
                      Value::DebugString(expr).c_str(), LOCF(loc()));
}

string IfStmt::DebugString() const {
  const char* opstr = "???";
  switch (op) {
    case CondOp::IFEQ:
      opstr = "ifeq";
      break;
    case CondOp::IFNEQ:
      opstr = "ifneq";
      break;
    case CondOp::IFDEF:
      opstr = "ifdef";
      break;
    case CondOp::IFNDEF:
      opstr = "ifndef";
      break;
  }
  return StringPrintf("IfStmt(op=%s, lhs=%s, rhs=%s t=%zu f=%zu loc=%s:%d)",
                      opstr, Value::DebugString(lhs).c_str(),
                      Value::DebugString(rhs).c_str(), true_stmts.size(),
                      false_stmts.size(), LOCF(loc()));
}

string IncludeStmt::DebugString() const {
  return StringPrintf("IncludeStmt(%s, loc=%s:%d)",
                      Value::DebugString(expr).c_str(), LOCF(loc()));
}

string ExportStmt::DebugString() const {
  return StringPrintf("ExportStmt(%s, %d, loc=%s:%d)",
                      Value::DebugString(expr).c_str(), is_export, LOCF(loc()));
}

string ParseErrorStmt::DebugString() const {
  return StringPrintf("ParseErrorStmt(%s, loc=%s:%d)", msg.c_str(),
                      LOCF(loc()));
}

RuleStmt::~RuleStmt() {
  delete lhs;
  delete rhs;
}

void RuleStmt::Eval(Evaluator* ev) const {
  ev->EvalRule(this);
}

AssignStmt::~AssignStmt() {
  delete lhs;
  delete rhs;
}

void AssignStmt::Eval(Evaluator* ev) const {
  ev->EvalAssign(this);
}

CommandStmt::~CommandStmt() {
  delete expr;
}

void CommandStmt::Eval(Evaluator* ev) const {
  ev->EvalCommand(this);
}

IfStmt::~IfStmt() {
  delete lhs;
  delete rhs;
}

void IfStmt::Eval(Evaluator* ev) const {
  ev->EvalIf(this);
}

IncludeStmt::~IncludeStmt() {
  delete expr;
}

void IncludeStmt::Eval(Evaluator* ev) const {
  ev->EvalInclude(this);
}

ExportStmt::~ExportStmt() {
  delete expr;
}

void ExportStmt::Eval(Evaluator* ev) const {
  ev->EvalExport(this);
}

ParseErrorStmt::~ParseErrorStmt() {}

void ParseErrorStmt::Eval(Evaluator* ev) const {
  ev->set_loc(loc());
  ev->Error(msg);
}
