/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
   file Copyright.txt or https://cmake.org/licensing for details.  */
#include "cmOSXBundleGenerator.h"

#include "cmGeneratorTarget.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmStateTypes.h"
#include "cmSystemTools.h"
#include "cmTarget.h"

#include <cassert>
#include <utility>

class cmSourceFile;

cmOSXBundleGenerator::cmOSXBundleGenerator(cmGeneratorTarget* target,
                                           std::string configName)
  : GT(target)
  , Makefile(target->Target->GetMakefile())
  , LocalGenerator(target->GetLocalGenerator())
  , ConfigName(std::move(configName))
  , MacContentFolders(nullptr)
{
  if (this->MustSkip()) {
    return;
  }
}

bool cmOSXBundleGenerator::MustSkip()
{
  return !this->GT->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->GT->GetAppBundleDirectory(this->ConfigName,
                                         cmGeneratorTarget::FullLevel);
  cmSystemTools::MakeDirectory(out);
  this->Makefile->AddCMakeOutputFile(out);

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

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->GT->GetFrameworkDirectory(this->ConfigName,
                                    cmGeneratorTarget::ContentLevel);
  contentdir += "/";

  std::string newoutpath = outpath + "/" +
    this->GT->GetFrameworkDirectory(this->ConfigName,
                                    cmGeneratorTarget::FullLevel);

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

  // Configure the Info.plist file
  std::string plist = newoutpath;
  if (!this->Makefile->PlatformIsAppleEmbedded()) {
    // Put the Info.plist file into the Resources directory.
    this->MacContentFolders->insert("Resources");
    plist += "/Resources";
  }
  plist += "/Info.plist";
  std::string name = cmSystemTools::GetFilenameName(targetName);
  this->LocalGenerator->GenerateFrameworkInfoPList(this->GT, name,
                                                   plist.c_str());

  // Generate Versions directory only for MacOSX frameworks
  if (this->Makefile->PlatformIsAppleEmbedded()) {
    return;
  }

  // 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);

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

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

  // foo -> Versions/Current/foo
  oldName = "Versions/Current/";
  oldName += name;
  newName = contentdir;
  newName += name;
  cmSystemTools::RemoveFile(newName);
  cmSystemTools::CreateSymlink(oldName, newName);
  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);
    cmSystemTools::CreateSymlink(oldName, newName);
    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);
    cmSystemTools::CreateSymlink(oldName, newName);
    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);
    cmSystemTools::CreateSymlink(oldName, newName);
    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->GT->GetCFBundleDirectory(this->ConfigName,
                                        cmGeneratorTarget::FullLevel);
  cmSystemTools::MakeDirectory(out);
  this->Makefile->AddCMakeOutputFile(out);

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

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

  for (cmSourceFile const* source : sources) {
    cmGeneratorTarget::SourceFileFlags tsFlags =
      this->GT->GetTargetSourceFileFlags(source);
    if (tsFlags.Type != cmGeneratorTarget::SourceFileTypeNormal) {
      (*generator)(*source, tsFlags.MacFolder);
    }
  }
}

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

  std::string macdir = this->GT->GetMacContentDirectory(
    this->ConfigName, cmStateEnums::RuntimeBinaryArtifact);
  macdir += "/";
  macdir += pkgloc;
  cmSystemTools::MakeDirectory(macdir);

  // 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;
}
