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

#include "cmake.h"
#include "cmState.h"

// cmLibraryCommand
bool cmAddLibraryCommand
::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
{
  if(args.size() < 1 )
    {
    this->SetError("called with incorrect number of arguments");
    return false;
    }
  // Library type defaults to value of BUILD_SHARED_LIBS, if it exists,
  // otherwise it defaults to static library.
  cmState::TargetType type = cmState::SHARED_LIBRARY;
  if (cmSystemTools::IsOff(this->Makefile->GetDefinition("BUILD_SHARED_LIBS")))
    {
    type = cmState::STATIC_LIBRARY;
    }
  bool excludeFromAll = false;
  bool importTarget = false;
  bool importGlobal = false;

  std::vector<std::string>::const_iterator s = args.begin();

  std::string libName = *s;

  ++s;

  // If the second argument is "SHARED" or "STATIC", then it controls
  // the type of library.  Otherwise, it is treated as a source or
  // source list name. There may be two keyword arguments, check for them
  bool haveSpecifiedType = false;
  bool isAlias = false;
  while ( s != args.end() )
    {
    std::string libType = *s;
    if(libType == "STATIC")
      {
      if (type == cmState::INTERFACE_LIBRARY)
        {
        std::ostringstream e;
        e << "INTERFACE library specified with conflicting STATIC type.";
        this->SetError(e.str());
        return false;
        }
      ++s;
      type = cmState::STATIC_LIBRARY;
      haveSpecifiedType = true;
      }
    else if(libType == "SHARED")
      {
      if (type == cmState::INTERFACE_LIBRARY)
        {
        std::ostringstream e;
        e << "INTERFACE library specified with conflicting SHARED type.";
        this->SetError(e.str());
        return false;
        }
      ++s;
      type = cmState::SHARED_LIBRARY;
      haveSpecifiedType = true;
      }
    else if(libType == "MODULE")
      {
      if (type == cmState::INTERFACE_LIBRARY)
        {
        std::ostringstream e;
        e << "INTERFACE library specified with conflicting MODULE type.";
        this->SetError(e.str());
        return false;
        }
      ++s;
      type = cmState::MODULE_LIBRARY;
      haveSpecifiedType = true;
      }
    else if(libType == "OBJECT")
      {
      if (type == cmState::INTERFACE_LIBRARY)
        {
        std::ostringstream e;
        e << "INTERFACE library specified with conflicting OBJECT type.";
        this->SetError(e.str());
        return false;
        }
      ++s;
      type = cmState::OBJECT_LIBRARY;
      haveSpecifiedType = true;
      }
    else if(libType == "UNKNOWN")
      {
      if (type == cmState::INTERFACE_LIBRARY)
        {
        std::ostringstream e;
        e << "INTERFACE library specified with conflicting UNKNOWN type.";
        this->SetError(e.str());
        return false;
        }
      ++s;
      type = cmState::UNKNOWN_LIBRARY;
      haveSpecifiedType = true;
      }
    else if(libType == "ALIAS")
      {
      if (type == cmState::INTERFACE_LIBRARY)
        {
        std::ostringstream e;
        e << "INTERFACE library specified with conflicting ALIAS type.";
        this->SetError(e.str());
        return false;
        }
      ++s;
      isAlias = true;
      }
    else if(libType == "INTERFACE")
      {
      if (haveSpecifiedType)
        {
        std::ostringstream e;
        e << "INTERFACE library specified with conflicting/multiple types.";
        this->SetError(e.str());
        return false;
        }
      if (isAlias)
        {
        std::ostringstream e;
        e << "INTERFACE library specified with conflicting ALIAS type.";
        this->SetError(e.str());
        return false;
        }
      if (excludeFromAll)
        {
        std::ostringstream e;
        e << "INTERFACE library may not be used with EXCLUDE_FROM_ALL.";
        this->SetError(e.str());
        return false;
        }
      ++s;
      type = cmState::INTERFACE_LIBRARY;
      haveSpecifiedType = true;
      }
    else if(*s == "EXCLUDE_FROM_ALL")
      {
      if (type == cmState::INTERFACE_LIBRARY)
        {
        std::ostringstream e;
        e << "INTERFACE library may not be used with EXCLUDE_FROM_ALL.";
        this->SetError(e.str());
        return false;
        }
      ++s;
      excludeFromAll = true;
      }
    else if(*s == "IMPORTED")
      {
      ++s;
      importTarget = true;
      }
    else if(importTarget && *s == "GLOBAL")
      {
      ++s;
      importGlobal = true;
      }
    else if(type == cmState::INTERFACE_LIBRARY && *s == "GLOBAL")
      {
      std::ostringstream e;
      e << "GLOBAL option may only be used with IMPORTED libraries.";
      this->SetError(e.str());
      return false;
      }
    else
      {
      break;
      }
    }

  if (type == cmState::INTERFACE_LIBRARY)
    {
    if (s != args.end())
      {
      std::ostringstream e;
      e << "INTERFACE library requires no source arguments.";
      this->SetError(e.str());
      return false;
      }
    if (importGlobal && !importTarget)
      {
      std::ostringstream e;
      e << "INTERFACE library specified as GLOBAL, but not as IMPORTED.";
      this->SetError(e.str());
      return false;
      }
    }

  bool nameOk = cmGeneratorExpression::IsValidTargetName(libName) &&
    !cmGlobalGenerator::IsReservedTarget(libName);

  if (nameOk && !importTarget && !isAlias)
    {
    nameOk = libName.find(":") == std::string::npos;
    }
  if (!nameOk)
    {
    cmake::MessageType messageType = cmake::AUTHOR_WARNING;
    std::ostringstream e;
    bool issueMessage = false;
    switch(this->Makefile->GetPolicyStatus(cmPolicies::CMP0037))
      {
      case cmPolicies::WARN:
        if(type != cmState::INTERFACE_LIBRARY)
          {
          e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0037) << "\n";
          issueMessage = true;
          }
      case cmPolicies::OLD:
        break;
      case cmPolicies::NEW:
      case cmPolicies::REQUIRED_IF_USED:
      case cmPolicies::REQUIRED_ALWAYS:
        issueMessage = true;
        messageType = cmake::FATAL_ERROR;
      }
    if (issueMessage)
      {
      e << "The target name \"" << libName <<
          "\" is reserved or not valid for certain "
          "CMake features, such as generator expressions, and may result "
          "in undefined behavior.";
      this->Makefile->IssueMessage(messageType, e.str());

      if (messageType == cmake::FATAL_ERROR)
        {
        return false;
        }
      }
    }

  if (isAlias)
    {
    if(!cmGeneratorExpression::IsValidTargetName(libName))
      {
      this->SetError("Invalid name for ALIAS: " + libName);
      return false;
      }
    if(excludeFromAll)
      {
      this->SetError("EXCLUDE_FROM_ALL with ALIAS makes no sense.");
      return false;
      }
    if(importTarget || importGlobal)
      {
      this->SetError("IMPORTED with ALIAS is not allowed.");
      return false;
      }
    if(args.size() != 3)
      {
      std::ostringstream e;
      e << "ALIAS requires exactly one target argument.";
      this->SetError(e.str());
      return false;
      }

    const char *aliasedName = s->c_str();
    if(this->Makefile->IsAlias(aliasedName))
      {
      std::ostringstream e;
      e << "cannot create ALIAS target \"" << libName
        << "\" because target \"" << aliasedName << "\" is itself an ALIAS.";
      this->SetError(e.str());
      return false;
      }
    cmTarget *aliasedTarget =
                    this->Makefile->FindTargetToUse(aliasedName, true);
    if(!aliasedTarget)
      {
      std::ostringstream e;
      e << "cannot create ALIAS target \"" << libName
        << "\" because target \"" << aliasedName << "\" does not already "
        "exist.";
      this->SetError(e.str());
      return false;
      }
    cmState::TargetType aliasedType = aliasedTarget->GetType();
    if(aliasedType != cmState::SHARED_LIBRARY
        && aliasedType != cmState::STATIC_LIBRARY
        && aliasedType != cmState::MODULE_LIBRARY
        && aliasedType != cmState::OBJECT_LIBRARY
        && aliasedType != cmState::INTERFACE_LIBRARY)
      {
      std::ostringstream e;
      e << "cannot create ALIAS target \"" << libName
        << "\" because target \"" << aliasedName << "\" is not a library.";
      this->SetError(e.str());
      return false;
      }
    if(aliasedTarget->IsImported())
      {
      std::ostringstream e;
      e << "cannot create ALIAS target \"" << libName
        << "\" because target \"" << aliasedName << "\" is IMPORTED.";
      this->SetError(e.str());
      return false;
      }
    this->Makefile->AddAlias(libName, aliasedName);
    return true;
    }

  if(importTarget && excludeFromAll)
    {
    this->SetError("excludeFromAll with IMPORTED target makes no sense.");
    return false;
    }

  /* ideally we should check whether for the linker language of the target
    CMAKE_${LANG}_CREATE_SHARED_LIBRARY is defined and if not default to
    STATIC. But at this point we know only the name of the target, but not
    yet its linker language. */
  if ((type == cmState::SHARED_LIBRARY ||
       type == cmState::MODULE_LIBRARY) &&
       (this->Makefile->GetState()->GetGlobalPropertyAsBool(
                                      "TARGET_SUPPORTS_SHARED_LIBS") == false))
    {
    std::ostringstream w;
    w <<
      "ADD_LIBRARY called with " <<
      (type==cmState::SHARED_LIBRARY ? "SHARED" : "MODULE") <<
      " option but the target platform does not support dynamic linking. "
      "Building a STATIC library instead. This may lead to problems.";
    this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, w.str());
    type = cmState::STATIC_LIBRARY;
    }

  // Handle imported target creation.
  if(importTarget)
    {
    // The IMPORTED signature requires a type to be specified explicitly.
    if (!haveSpecifiedType)
      {
      this->SetError("called with IMPORTED argument but no library type.");
      return false;
      }
    if(type == cmState::OBJECT_LIBRARY)
      {
      this->Makefile->IssueMessage(
        cmake::FATAL_ERROR,
        "The OBJECT library type may not be used for IMPORTED libraries."
        );
      return true;
      }
    if(type == cmState::INTERFACE_LIBRARY)
      {
      if (!cmGeneratorExpression::IsValidTargetName(libName))
        {
        std::ostringstream e;
        e << "Invalid name for IMPORTED INTERFACE library target: " << libName;
        this->SetError(e.str());
        return false;
        }
      }

    // Make sure the target does not already exist.
    if(this->Makefile->FindTargetToUse(libName))
      {
      std::ostringstream e;
      e << "cannot create imported target \"" << libName
        << "\" because another target with the same name already exists.";
      this->SetError(e.str());
      return false;
      }

    // Create the imported target.
    this->Makefile->AddImportedTarget(libName, type, importGlobal);
    return true;
    }

  // A non-imported target may not have UNKNOWN type.
  if(type == cmState::UNKNOWN_LIBRARY)
    {
    this->Makefile->IssueMessage(
      cmake::FATAL_ERROR,
      "The UNKNOWN library type may be used only for IMPORTED libraries."
      );
    return true;
    }

  // Enforce name uniqueness.
  {
  std::string msg;
  if(!this->Makefile->EnforceUniqueName(libName, msg))
    {
    this->SetError(msg);
    return false;
    }
  }

  std::vector<std::string> srclists;

  if(type == cmState::INTERFACE_LIBRARY)
    {
    if (!cmGeneratorExpression::IsValidTargetName(libName)
        || libName.find("::") != std::string::npos)
      {
      std::ostringstream e;
      e << "Invalid name for INTERFACE library target: " << libName;
      this->SetError(e.str());
      return false;
      }

    this->Makefile->AddLibrary(libName,
                               type,
                               srclists,
                               excludeFromAll);
    return true;
    }

  if (s == args.end())
    {
    std::string msg = "You have called ADD_LIBRARY for library ";
    msg += args[0];
    msg += " without any source files. This typically indicates a problem ";
    msg += "with your CMakeLists.txt file";
    cmSystemTools::Message(msg.c_str() ,"Warning");
    }

  srclists.insert(srclists.end(), s, args.end());

  this->Makefile->AddLibrary(libName, type, srclists, excludeFromAll);

  return true;
}


