/*============================================================================
  CMake - Cross Platform Makefile Generator
  Copyright 2000-2009 Kitware, Inc., Insight Software Consortium

  Distributed under the OSI-approved BSD License (the "License");
  see accompanying file Copyright.txt for details.

  This software is distributed WITHOUT ANY WARRANTY; without even the
  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  See the License for more information.
============================================================================*/
#include "cmIfCommand.h"

#include "cmOutputConverter.h"
#include "cmStringCommand.h"

#include "cmConditionEvaluator.h"

#include <cmsys/RegularExpression.hxx>
#include <list>
#include <stdlib.h> // required for atof

static std::string cmIfCommandError(
  std::vector<cmExpandedCommandArgument> const& args)
{
  std::string err = "given arguments:\n ";
  for (std::vector<cmExpandedCommandArgument>::const_iterator i = args.begin();
       i != args.end(); ++i) {
    err += " ";
    err += cmOutputConverter::EscapeForCMake(i->GetValue());
  }
  err += "\n";
  return err;
}

//=========================================================================
bool cmIfFunctionBlocker::IsFunctionBlocked(const cmListFileFunction& lff,
                                            cmMakefile& mf,
                                            cmExecutionStatus& inStatus)
{
  // we start by recording all the functions
  if (!cmSystemTools::Strucmp(lff.Name.c_str(), "if")) {
    this->ScopeDepth++;
  } else if (!cmSystemTools::Strucmp(lff.Name.c_str(), "endif")) {
    this->ScopeDepth--;
    // if this is the endif for this if statement, then start executing
    if (!this->ScopeDepth) {
      // Remove the function blocker for this scope or bail.
      cmsys::auto_ptr<cmFunctionBlocker> fb(
        mf.RemoveFunctionBlocker(this, lff));
      if (!fb.get()) {
        return false;
      }

      // execute the functions for the true parts of the if statement
      cmExecutionStatus status;
      int scopeDepth = 0;
      for (unsigned int c = 0; c < this->Functions.size(); ++c) {
        // keep track of scope depth
        if (!cmSystemTools::Strucmp(this->Functions[c].Name.c_str(), "if")) {
          scopeDepth++;
        }
        if (!cmSystemTools::Strucmp(this->Functions[c].Name.c_str(),
                                    "endif")) {
          scopeDepth--;
        }
        // watch for our state change
        if (scopeDepth == 0 &&
            !cmSystemTools::Strucmp(this->Functions[c].Name.c_str(), "else")) {
          this->IsBlocking = this->HasRun;
          this->HasRun = true;

          // if trace is enabled, print a (trivially) evaluated "else"
          // statement
          if (!this->IsBlocking && mf.GetCMakeInstance()->GetTrace()) {
            mf.PrintCommandTrace(this->Functions[c]);
          }
        } else if (scopeDepth == 0 &&
                   !cmSystemTools::Strucmp(this->Functions[c].Name.c_str(),
                                           "elseif")) {
          if (this->HasRun) {
            this->IsBlocking = true;
          } else {
            // if trace is enabled, print the evaluated "elseif" statement
            if (mf.GetCMakeInstance()->GetTrace()) {
              mf.PrintCommandTrace(this->Functions[c]);
            }

            std::string errorString;

            std::vector<cmExpandedCommandArgument> expandedArguments;
            mf.ExpandArguments(this->Functions[c].Arguments,
                               expandedArguments);

            cmake::MessageType messType;

            cmListFileContext conditionContext =
              cmListFileContext::FromCommandContext(
                this->Functions[c], this->GetStartingContext().FilePath);

            cmConditionEvaluator conditionEvaluator(
              mf, conditionContext, mf.GetBacktrace(this->Functions[c]));

            bool isTrue = conditionEvaluator.IsTrue(expandedArguments,
                                                    errorString, messType);

            if (!errorString.empty()) {
              std::string err = cmIfCommandError(expandedArguments);
              err += errorString;
              cmListFileBacktrace bt = mf.GetBacktrace(this->Functions[c]);
              mf.GetCMakeInstance()->IssueMessage(messType, err, bt);
              if (messType == cmake::FATAL_ERROR) {
                cmSystemTools::SetFatalErrorOccured();
                return true;
              }
            }

            if (isTrue) {
              this->IsBlocking = false;
              this->HasRun = true;
            }
          }
        }

        // should we execute?
        else if (!this->IsBlocking) {
          status.Clear();
          mf.ExecuteCommand(this->Functions[c], status);
          if (status.GetReturnInvoked()) {
            inStatus.SetReturnInvoked(true);
            return true;
          }
          if (status.GetBreakInvoked()) {
            inStatus.SetBreakInvoked(true);
            return true;
          }
          if (status.GetContinueInvoked()) {
            inStatus.SetContinueInvoked(true);
            return true;
          }
        }
      }
      return true;
    }
  }

  // record the command
  this->Functions.push_back(lff);

  // always return true
  return true;
}

//=========================================================================
bool cmIfFunctionBlocker::ShouldRemove(const cmListFileFunction& lff,
                                       cmMakefile&)
{
  if (!cmSystemTools::Strucmp(lff.Name.c_str(), "endif")) {
    // if the endif has arguments, then make sure
    // they match the arguments of the matching if
    if (lff.Arguments.empty() || lff.Arguments == this->Args) {
      return true;
    }
  }

  return false;
}

//=========================================================================
bool cmIfCommand::InvokeInitialPass(
  const std::vector<cmListFileArgument>& args, cmExecutionStatus&)
{
  std::string errorString;

  std::vector<cmExpandedCommandArgument> expandedArguments;
  this->Makefile->ExpandArguments(args, expandedArguments);

  cmake::MessageType status;

  cmConditionEvaluator conditionEvaluator(
    *(this->Makefile), this->Makefile->GetExecutionContext(),
    this->Makefile->GetBacktrace());

  bool isTrue =
    conditionEvaluator.IsTrue(expandedArguments, errorString, status);

  if (!errorString.empty()) {
    std::string err = cmIfCommandError(expandedArguments);
    err += errorString;
    if (status == cmake::FATAL_ERROR) {
      this->SetError(err);
      cmSystemTools::SetFatalErrorOccured();
      return false;
    } else {
      this->Makefile->IssueMessage(status, err);
    }
  }

  cmIfFunctionBlocker* f = new cmIfFunctionBlocker();
  // if is isn't true block the commands
  f->ScopeDepth = 1;
  f->IsBlocking = !isTrue;
  if (isTrue) {
    f->HasRun = true;
  }
  f->Args = args;
  this->Makefile->AddFunctionBlocker(f);

  return true;
}
