/*============================================================================
  CMake - Cross Platform Makefile Generator
  Copyright 2012 Nicolas Despres <nicolas.despres@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 "cmOSXBundleGenerator.h"
#include "cmMakefile.h"
#include "cmTarget.h"
#include "cmLocalGenerator.h"

#include <cassert>

//----------------------------------------------------------------------------
cmOSXBundleGenerator::
cmOSXBundleGenerator(cmGeneratorTarget* target,
                     const char* configName)
 : Target(target->Target)
 , Makefile(target->Target->GetMakefile())
 , LocalGenerator(Makefile->GetLocalGenerator())
 , ConfigName(configName)
 , MacContentFolders(0)
{
  if (this->MustSkip())
    return;

}

//----------------------------------------------------------------------------
bool cmOSXBundleGenerator::MustSkip()
{
  return !this->Target->HaveWellDefinedOutputFiles();
}

//----------------------------------------------------------------------------
void cmOSXBundleGenerator::CreateAppBundle(const std::string& targetName,
                                           std::string& outpath)
{
  if (this->MustSkip())
    return;

  // Compute bundle directory names.
  std::string out = outpath;
  out += "/";
  out += this->Target->GetAppBundleDirectory(this->ConfigName, false);
  cmSystemTools::MakeDirectory(out.c_str());
  this->Makefile->AddCMakeOutputFile(out);

  std::string newoutpath = out;

  // Configure the Info.plist file.  Note that it needs the executable name
  // to be set.
  std::string plist = outpath;
  plist += "/";
  plist += this->Target->GetAppBundleDirectory(this->ConfigName, true);
  plist += "/Info.plist";
  this->LocalGenerator->GenerateAppleInfoPList(this->Target,
                                               targetName.c_str(),
                                               plist.c_str());
  this->Makefile->AddCMakeOutputFile(plist);
  outpath = newoutpath;
}

//----------------------------------------------------------------------------
void cmOSXBundleGenerator::CreateFramework(
  const std::string& targetName, const std::string& outpath)
{
  if (this->MustSkip())
    return;

  assert(this->MacContentFolders);

  // Compute the location of the top-level foo.framework directory.
  std::string contentdir = outpath + "/" +
    this->Target->GetFrameworkDirectory(this->ConfigName, true);
  contentdir += "/";

  std::string newoutpath = outpath + "/" +
    this->Target->GetFrameworkDirectory(this->ConfigName, false);

  std::string frameworkVersion = this->Target->GetFrameworkVersion();

  // Configure the Info.plist file into the Resources directory.
  this->MacContentFolders->insert("Resources");
  std::string plist = newoutpath;
  plist += "/Resources/Info.plist";
  std::string name = cmSystemTools::GetFilenameName(targetName);
  this->LocalGenerator->GenerateFrameworkInfoPList(this->Target,
                                                   name.c_str(),
                                                   plist.c_str());

  // TODO: Use the cmMakefileTargetGenerator::ExtraFiles vector to
  // drive rules to create these files at build time.
  std::string oldName;
  std::string newName;


  // Make foo.framework/Versions
  std::string versions = contentdir;
  versions += "Versions";
  cmSystemTools::MakeDirectory(versions.c_str());

  // Make foo.framework/Versions/version
  cmSystemTools::MakeDirectory(newoutpath.c_str());

  // Current -> version
  oldName = frameworkVersion;
  newName = versions;
  newName += "/Current";
  cmSystemTools::RemoveFile(newName.c_str());
  cmSystemTools::CreateSymlink(oldName.c_str(), newName.c_str());
  this->Makefile->AddCMakeOutputFile(newName);

  // foo -> Versions/Current/foo
  oldName = "Versions/Current/";
  oldName += name;
  newName = contentdir;
  newName += name;
  cmSystemTools::RemoveFile(newName.c_str());
  cmSystemTools::CreateSymlink(oldName.c_str(), newName.c_str());
  this->Makefile->AddCMakeOutputFile(newName);

  // Resources -> Versions/Current/Resources
  if(this->MacContentFolders->find("Resources") !=
     this->MacContentFolders->end())
    {
    oldName = "Versions/Current/Resources";
    newName = contentdir;
    newName += "Resources";
    cmSystemTools::RemoveFile(newName.c_str());
    cmSystemTools::CreateSymlink(oldName.c_str(), newName.c_str());
    this->Makefile->AddCMakeOutputFile(newName);
    }

  // Headers -> Versions/Current/Headers
  if(this->MacContentFolders->find("Headers") !=
     this->MacContentFolders->end())
    {
    oldName = "Versions/Current/Headers";
    newName = contentdir;
    newName += "Headers";
    cmSystemTools::RemoveFile(newName.c_str());
    cmSystemTools::CreateSymlink(oldName.c_str(), newName.c_str());
    this->Makefile->AddCMakeOutputFile(newName);
    }

  // PrivateHeaders -> Versions/Current/PrivateHeaders
  if(this->MacContentFolders->find("PrivateHeaders") !=
     this->MacContentFolders->end())
    {
    oldName = "Versions/Current/PrivateHeaders";
    newName = contentdir;
    newName += "PrivateHeaders";
    cmSystemTools::RemoveFile(newName.c_str());
    cmSystemTools::CreateSymlink(oldName.c_str(), newName.c_str());
    this->Makefile->AddCMakeOutputFile(newName);
    }
}

//----------------------------------------------------------------------------
void cmOSXBundleGenerator::CreateCFBundle(const std::string& targetName,
                                          const std::string& root)
{
  if (this->MustSkip())
    return;

  // Compute bundle directory names.
  std::string out = root;
  out += "/";
  out += this->Target->GetCFBundleDirectory(this->ConfigName, false);
  cmSystemTools::MakeDirectory(out.c_str());
  this->Makefile->AddCMakeOutputFile(out);

  // Configure the Info.plist file.  Note that it needs the executable name
  // to be set.
  std::string plist =
    this->Target->GetCFBundleDirectory(this->ConfigName, true);
  plist += "/Info.plist";
  this->LocalGenerator->GenerateAppleInfoPList(this->Target,
                                               targetName.c_str(),
                                               plist.c_str());
  this->Makefile->AddCMakeOutputFile(plist);
}

//----------------------------------------------------------------------------
void
cmOSXBundleGenerator::
GenerateMacOSXContentStatements(std::vector<cmSourceFile*> const& sources,
                                MacOSXContentGeneratorType* generator)
{
  if (this->MustSkip())
    return;

  for(std::vector<cmSourceFile*>::const_iterator
        si = sources.begin(); si != sources.end(); ++si)
    {
    cmTarget::SourceFileFlags tsFlags =
      this->Target->GetTargetSourceFileFlags(*si);
    if(tsFlags.Type != cmTarget::SourceFileTypeNormal)
      {
      (*generator)(**si, tsFlags.MacFolder);
      }
    }
}

//----------------------------------------------------------------------------
std::string
cmOSXBundleGenerator::InitMacOSXContentDirectory(const char* pkgloc)
{
  // Construct the full path to the content subdirectory.

  std::string macdir =
    this->Target->GetMacContentDirectory(this->ConfigName,
                                         /*implib*/ false);
  macdir += "/";
  macdir += pkgloc;
  cmSystemTools::MakeDirectory(macdir.c_str());

  // Record use of this content location.  Only the first level
  // directory is needed.
  {
  std::string loc = pkgloc;
  loc = loc.substr(0, loc.find('/'));
  this->MacContentFolders->insert(loc);
  }

  return macdir;
}
