/*============================================================================
  CMake - Cross Platform Makefile Generator
  Copyright 2013 Stephen Kelly <steveire@gmail.com>

  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 "cmGeneratorExpressionEvaluationFile.h"

#include "cmMakefile.h"
#include "cmLocalGenerator.h"
#include "cmGlobalGenerator.h"
#include "cmSourceFile.h"
#include "cmGeneratedFileStream.h"
#include <cmsys/FStream.hxx>

#include <assert.h>

//----------------------------------------------------------------------------
cmGeneratorExpressionEvaluationFile::cmGeneratorExpressionEvaluationFile(
        const std::string &input,
        cmsys::auto_ptr<cmCompiledGeneratorExpression> outputFileExpr,
        cmMakefile *makefile,
        cmsys::auto_ptr<cmCompiledGeneratorExpression> condition,
        bool inputIsContent)
  : Input(input),
    OutputFileExpr(outputFileExpr),
    Makefile(makefile),
    Condition(condition),
    InputIsContent(inputIsContent)
{
}

//----------------------------------------------------------------------------
void cmGeneratorExpressionEvaluationFile::Generate(const std::string& config,
              cmCompiledGeneratorExpression* inputExpression,
              std::map<std::string, std::string> &outputFiles, mode_t perm)
{
  std::string rawCondition = this->Condition->GetInput();
  if (!rawCondition.empty())
    {
    std::string condResult = this->Condition->Evaluate(this->Makefile, config);
    if (condResult == "0")
      {
      return;
      }
    if (condResult != "1")
      {
      std::ostringstream e;
      e << "Evaluation file condition \"" << rawCondition << "\" did "
          "not evaluate to valid content. Got \"" << condResult << "\".";
      this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
      return;
      }
    }

  const std::string outputFileName
                    = this->OutputFileExpr->Evaluate(this->Makefile, config);
  const std::string outputContent
                          = inputExpression->Evaluate(this->Makefile, config);

  std::map<std::string, std::string>::iterator it
                                          = outputFiles.find(outputFileName);

  if(it != outputFiles.end())
    {
    if (it->second == outputContent)
      {
      return;
      }
    std::ostringstream e;
    e << "Evaluation file to be written multiple times for different "
         "configurations with different content:\n  " << outputFileName;
    this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
    return;
    }

  this->Makefile->AddCMakeOutputFile(outputFileName.c_str());
  this->Files.push_back(outputFileName);
  outputFiles[outputFileName] = outputContent;

  cmGeneratedFileStream fout(outputFileName.c_str());
  fout.SetCopyIfDifferent(true);
  fout << outputContent;
  if (fout.Close() && perm)
    {
    cmSystemTools::SetPermissions(outputFileName.c_str(), perm);
    }
}

//----------------------------------------------------------------------------
void cmGeneratorExpressionEvaluationFile::CreateOutputFile(
                                              std::string const& config)
{
  std::string name = this->OutputFileExpr->Evaluate(this->Makefile, config);
  cmSourceFile* sf = this->Makefile->GetOrCreateSource(name);
  sf->SetProperty("GENERATED", "1");

  cmGlobalGenerator *gg
                  = this->Makefile->GetLocalGenerator()->GetGlobalGenerator();
  gg->SetFilenameTargetDepends(sf,
                          this->OutputFileExpr->GetSourceSensitiveTargets());
}

//----------------------------------------------------------------------------
void cmGeneratorExpressionEvaluationFile::Generate()
{
  mode_t perm = 0;
  std::string inputContent;
  if (this->InputIsContent)
    {
    inputContent = this->Input;
    }
  else
    {
    this->Makefile->AddCMakeDependFile(this->Input.c_str());
    cmSystemTools::GetPermissions(this->Input.c_str(), perm);
    cmsys::ifstream fin(this->Input.c_str());
    if(!fin)
      {
      std::ostringstream e;
      e << "Evaluation file \"" << this->Input << "\" cannot be read.";
      this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
      return;
      }

    std::string line;
    std::string sep;
    while(cmSystemTools::GetLineFromStream(fin, line))
      {
      inputContent += sep + line;
      sep = "\n";
      }
    inputContent += sep;
    }

  cmListFileBacktrace lfbt = this->OutputFileExpr->GetBacktrace();
  cmGeneratorExpression contentGE(&lfbt);
  cmsys::auto_ptr<cmCompiledGeneratorExpression> inputExpression
                                              = contentGE.Parse(inputContent);

  std::map<std::string, std::string> outputFiles;

  std::vector<std::string> allConfigs;
  this->Makefile->GetConfigurations(allConfigs);

  if (allConfigs.empty())
    {
    allConfigs.push_back("");
    }
  for(std::vector<std::string>::const_iterator li = allConfigs.begin();
      li != allConfigs.end(); ++li)
    {
    this->Generate(*li, inputExpression.get(), outputFiles, perm);
    if(cmSystemTools::GetFatalErrorOccured())
      {
      return;
      }
    }
}
