/*============================================================================
  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 "cmAddCustomCommandCommand.h"

#include "cmTarget.h"

#include "cmSourceFile.h"

// cmAddCustomCommandCommand
bool cmAddCustomCommandCommand
::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
{
  /* Let's complain at the end of this function about the lack of a particular
     arg. For the moment, let's say that COMMAND, and either TARGET or SOURCE
     are required.
  */
  if (args.size() < 4)
    {
      this->SetError("called with wrong number of arguments.");
      return false;
    }

  std::string source, target, main_dependency, working;
  std::string comment_buffer;
  const char* comment = 0;
  std::vector<std::string> depends, outputs, output, byproducts;
  bool verbatim = false;
  bool append = false;
  bool uses_terminal = false;
  std::string implicit_depends_lang;
  cmCustomCommand::ImplicitDependsList implicit_depends;

  // Accumulate one command line at a time.
  cmCustomCommandLine currentLine;

  // Save all command lines.
  cmCustomCommandLines commandLines;

  cmTarget::CustomCommandType cctype = cmTarget::POST_BUILD;

  enum tdoing {
    doing_source,
    doing_command,
    doing_target,
    doing_depends,
    doing_implicit_depends_lang,
    doing_implicit_depends_file,
    doing_main_dependency,
    doing_output,
    doing_outputs,
    doing_byproducts,
    doing_comment,
    doing_working_directory,
    doing_nothing
  };

  tdoing doing = doing_nothing;

  for (unsigned int j = 0; j < args.size(); ++j)
    {
    std::string const& copy = args[j];

    if(copy == "SOURCE")
      {
      doing = doing_source;
      }
    else if(copy == "COMMAND")
      {
      doing = doing_command;

      // Save the current command before starting the next command.
      if(!currentLine.empty())
        {
        commandLines.push_back(currentLine);
        currentLine.clear();
        }
      }
    else if(copy == "PRE_BUILD")
      {
      cctype = cmTarget::PRE_BUILD;
      }
    else if(copy == "PRE_LINK")
      {
      cctype = cmTarget::PRE_LINK;
      }
    else if(copy == "POST_BUILD")
      {
      cctype = cmTarget::POST_BUILD;
      }
    else if(copy == "VERBATIM")
      {
      verbatim = true;
      }
    else if(copy == "APPEND")
      {
      append = true;
      }
    else if(copy == "USES_TERMINAL")
      {
      uses_terminal = true;
      }
    else if(copy == "TARGET")
      {
      doing = doing_target;
      }
    else if(copy == "ARGS")
      {
      // Ignore this old keyword.
      }
    else if (copy == "DEPENDS")
      {
      doing = doing_depends;
      }
    else if (copy == "OUTPUTS")
      {
      doing = doing_outputs;
      }
    else if (copy == "OUTPUT")
      {
      doing = doing_output;
      }
    else if (copy == "BYPRODUCTS")
      {
      doing = doing_byproducts;
      }
    else if (copy == "WORKING_DIRECTORY")
      {
      doing = doing_working_directory;
      }
    else if (copy == "MAIN_DEPENDENCY")
      {
      doing = doing_main_dependency;
      }
    else if (copy == "IMPLICIT_DEPENDS")
      {
      doing = doing_implicit_depends_lang;
      }
    else if (copy == "COMMENT")
      {
      doing = doing_comment;
      }
    else
      {
      std::string filename;
      switch (doing)
        {
        case doing_output:
        case doing_outputs:
        case doing_byproducts:
          if (!cmSystemTools::FileIsFullPath(copy.c_str()))
            {
            // This is an output to be generated, so it should be
            // under the build tree.  CMake 2.4 placed this under the
            // source tree.  However the only case that this change
            // will break is when someone writes
            //
            //   add_custom_command(OUTPUT out.txt ...)
            //
            // and later references "${CMAKE_CURRENT_SOURCE_DIR}/out.txt".
            // This is fairly obscure so we can wait for someone to
            // complain.
            filename = this->Makefile->GetCurrentBinaryDirectory();
            filename += "/";
            }
          filename += copy;
          cmSystemTools::ConvertToUnixSlashes(filename);
          break;
        case doing_source:
          // We do not want to convert the argument to SOURCE because
          // that option is only available for backward compatibility.
          // Old-style use of this command may use the SOURCE==TARGET
          // trick which we must preserve.  If we convert the source
          // to a full path then it will no longer equal the target.
        default:
          break;
        }

      if (cmSystemTools::FileIsFullPath(filename.c_str()))
        {
        filename = cmSystemTools::CollapseFullPath(filename);
        }
       switch (doing)
         {
         case doing_working_directory:
           working = copy;
           break;
         case doing_source:
           source = copy;
           break;
         case doing_output:
           output.push_back(filename);
           break;
         case doing_main_dependency:
           main_dependency = copy;
           break;
         case doing_implicit_depends_lang:
           implicit_depends_lang = copy;
           doing = doing_implicit_depends_file;
           break;
         case doing_implicit_depends_file:
           {
           // An implicit dependency starting point is also an
           // explicit dependency.
           std::string dep = copy;
           cmSystemTools::ConvertToUnixSlashes(dep);
           depends.push_back(dep);

           // Add the implicit dependency language and file.
           cmCustomCommand::ImplicitDependsPair
             entry(implicit_depends_lang, dep);
           implicit_depends.push_back(entry);

           // Switch back to looking for a language.
           doing = doing_implicit_depends_lang;
           }
           break;
         case doing_command:
           currentLine.push_back(copy);
           break;
         case doing_target:
           target = copy;
           break;
         case doing_depends:
           {
           std::string dep = copy;
           cmSystemTools::ConvertToUnixSlashes(dep);
           depends.push_back(dep);
           }
           break;
         case doing_outputs:
           outputs.push_back(filename);
           break;
         case doing_byproducts:
           byproducts.push_back(filename);
           break;
         case doing_comment:
           comment_buffer = copy;
           comment = comment_buffer.c_str();
           break;
         default:
           this->SetError("Wrong syntax. Unknown type of argument.");
           return false;
         }
      }
    }

  // Store the last command line finished.
  if(!currentLine.empty())
    {
    commandLines.push_back(currentLine);
    currentLine.clear();
    }

  // At this point we could complain about the lack of arguments.  For
  // the moment, let's say that COMMAND, TARGET are always required.
  if(output.empty() && target.empty())
    {
    this->SetError("Wrong syntax. A TARGET or OUTPUT must be specified.");
    return false;
    }

  if(source.empty() && !target.empty() && !output.empty())
    {
    this->SetError(
      "Wrong syntax. A TARGET and OUTPUT can not both be specified.");
    return false;
    }
  if(append && output.empty())
    {
    this->SetError("given APPEND option with no OUTPUT.");
    return false;
    }

  // Make sure the output names and locations are safe.
  if(!this->CheckOutputs(output) ||
     !this->CheckOutputs(outputs) ||
     !this->CheckOutputs(byproducts))
    {
    return false;
    }

  // Check for an append request.
  if(append)
    {
    // Lookup an existing command.
    if(cmSourceFile* sf =
       this->Makefile->GetSourceFileWithOutput(output[0]))
      {
      if(cmCustomCommand* cc = sf->GetCustomCommand())
        {
        cc->AppendCommands(commandLines);
        cc->AppendDepends(depends);
        cc->AppendImplicitDepends(implicit_depends);
        return true;
        }
      }

    // No command for this output exists.
    std::ostringstream e;
    e << "given APPEND option with output \"" << output[0]
      << "\" which is not already a custom command output.";
    this->SetError(e.str());
    return false;
    }

  // Convert working directory to a full path.
  if(!working.empty())
    {
    const char* build_dir = this->Makefile->GetCurrentBinaryDirectory();
    working = cmSystemTools::CollapseFullPath(working, build_dir);
    }

  // Choose which mode of the command to use.
  bool escapeOldStyle = !verbatim;
  if(source.empty() && output.empty())
    {
    // Source is empty, use the target.
    std::vector<std::string> no_depends;
    this->Makefile->AddCustomCommandToTarget(target, byproducts, no_depends,
                                             commandLines, cctype,
                                             comment, working.c_str(),
                                             escapeOldStyle, uses_terminal);
    }
  else if(target.empty())
    {
    // Target is empty, use the output.
    this->Makefile->AddCustomCommandToOutput(output, byproducts,
                                             depends, main_dependency,
                                             commandLines, comment,
                                             working.c_str(), false,
                                             escapeOldStyle, uses_terminal);

    // Add implicit dependency scanning requests if any were given.
    if(!implicit_depends.empty())
      {
      bool okay = false;
      if(cmSourceFile* sf =
         this->Makefile->GetSourceFileWithOutput(output[0]))
        {
        if(cmCustomCommand* cc = sf->GetCustomCommand())
          {
          okay = true;
          cc->SetImplicitDepends(implicit_depends);
          }
        }
      if(!okay)
        {
        std::ostringstream e;
        e << "could not locate source file with a custom command producing \""
          << output[0] << "\" even though this command tried to create it!";
        this->SetError(e.str());
        return false;
        }
      }
    }
  else if (!byproducts.empty())
    {
    this->SetError("BYPRODUCTS may not be specified with SOURCE signatures");
    return false;
    }
  else if (uses_terminal)
    {
    this->SetError("USES_TERMINAL may not be used with SOURCE signatures");
    return false;
    }
  else
    {
    bool issueMessage = true;
    std::ostringstream e;
    cmake::MessageType messageType = cmake::AUTHOR_WARNING;
    switch(this->Makefile->GetPolicyStatus(cmPolicies::CMP0050))
    {
    case cmPolicies::WARN:
      e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0050) << "\n";
      break;
    case cmPolicies::OLD:
      issueMessage = false;
      break;
    case cmPolicies::REQUIRED_ALWAYS:
    case cmPolicies::REQUIRED_IF_USED:
    case cmPolicies::NEW:
      messageType = cmake::FATAL_ERROR;
      break;
    }

    if (issueMessage)
      {
      e << "The SOURCE signatures of add_custom_command are no longer "
           "supported.";
      this->Makefile->IssueMessage(messageType, e.str());
      if (messageType == cmake::FATAL_ERROR)
        {
        return false;
        }
      }

    // Use the old-style mode for backward compatibility.
    this->Makefile->AddCustomCommandOldStyle(target, outputs, depends,
                                             source, commandLines,
                                             comment);
    }

  return true;
}

//----------------------------------------------------------------------------
bool
cmAddCustomCommandCommand
::CheckOutputs(const std::vector<std::string>& outputs)
{
  for(std::vector<std::string>::const_iterator o = outputs.begin();
      o != outputs.end(); ++o)
    {
    // Make sure the file will not be generated into the source
    // directory during an out of source build.
    if(!this->Makefile->CanIWriteThisFile(o->c_str()))
      {
      std::string e = "attempted to have a file \"" + *o +
        "\" in a source directory as an output of custom command.";
      this->SetError(e);
      cmSystemTools::SetFatalErrorOccured();
      return false;
      }

    // Make sure the output file name has no invalid characters.
    std::string::size_type pos = o->find_first_of("#<>");
    if(pos != o->npos)
      {
      std::ostringstream msg;
      msg << "called with OUTPUT containing a \"" << (*o)[pos]
          << "\".  This character is not allowed.";
      this->SetError(msg.str());
      return false;
      }
    }
  return true;
}
