require 'fileutils'

module Pod
  # The sandbox provides support for the directory that CocoaPods uses for an
  # installation. In this directory the Pods projects, the support files and
  # the sources of the Pods are stored.
  #
  # CocoaPods assumes to have control of the sandbox.
  #
  # Once completed the sandbox will have the following file structure:
  #
  #     Pods
  #     |
  #     +-- Headers
  #     |   +-- Private
  #     |   |   +-- [Pod Name]
  #     |   +-- Public
  #     |       +-- [Pod Name]
  #     |
  #     +-- Local Podspecs
  #     |   +-- External Sources
  #     |   +-- Normal Sources
  #     |
  #     +-- Target Support Files
  #     |   +-- [Target Name]
  #     |       +-- Pods-acknowledgements.markdown
  #     |       +-- Pods-acknowledgements.plist
  #     |       +-- Pods-dummy.m
  #     |       +-- Pods-prefix.pch
  #     |       +-- Pods.xcconfig
  #     |
  #     +-- [Pod Name]
  #     |
  #     +-- Manifest.lock
  #     |
  #     +-- Pods.xcodeproj
  #
  class Sandbox
    autoload :FileAccessor,  'cocoapods/sandbox/file_accessor'
    autoload :HeadersStore,  'cocoapods/sandbox/headers_store'
    autoload :PathList,      'cocoapods/sandbox/path_list'
    autoload :PodDirCleaner, 'cocoapods/sandbox/pod_dir_cleaner'
    autoload :PodspecFinder, 'cocoapods/sandbox/podspec_finder'

    # @return [Pathname] the root of the sandbox.
    #
    attr_reader :root

    # @return [HeadersStore] the header directory for the user targets.
    #
    attr_reader :public_headers

    # Initialize a new instance
    #
    # @param [String, Pathname] root @see root
    #
    def initialize(root)
      FileUtils.mkdir_p(root)
      @root = Pathname.new(root).realpath
      @public_headers = HeadersStore.new(self, 'Public')
      @predownloaded_pods = []
      @checkout_sources = {}
      @development_pods = {}
      @pods_with_absolute_path = []
    end

    # @return [Lockfile] the manifest which contains the information about the
    #         installed pods.
    #
    attr_accessor :manifest

    def manifest
      @manifest ||= begin
        Lockfile.from_file(manifest_path) if manifest_path.exist?
      end
    end

    # @return [Project] the Pods project.
    #
    attr_accessor :project

    # Removes the files of the Pod with the given name from the sandbox.
    #
    # @return [void]
    #
    def clean_pod(name)
      root_name = Specification.root_name(name)
      unless local?(root_name)
        path = pod_dir(name)
        path.rmtree if path.exist?
      end
      podspec_path = specification_path(name)
      podspec_path.rmtree if podspec_path
    end

    # Prepares the sandbox for a new installation removing any file that will
    # be regenerated and ensuring that the directories exists.
    #
    def prepare
      FileUtils.rm_rf(headers_root)

      FileUtils.mkdir_p(headers_root)
      FileUtils.mkdir_p(sources_root)
      FileUtils.mkdir_p(specifications_root)
      FileUtils.mkdir_p(target_support_files_root)
    end

    # @return [String] a string representation suitable for debugging.
    #
    def inspect
      "#<#{self.class}> with root #{root}"
    end

    #-------------------------------------------------------------------------#

    public

    # @!group Paths

    # @return [Pathname] the path of the manifest.
    #
    def manifest_path
      root + 'Manifest.lock'
    end

    # @return [Pathname] the path of the Pods project.
    #
    def project_path
      root + 'Pods.xcodeproj'
    end

    # Returns the path for the directory where the support files of
    # a target are stored.
    #
    # @param  [String] name
    #         The name of the target.
    #
    # @return [Pathname] the path of the support files.
    #
    def target_support_files_dir(name)
      target_support_files_root + name
    end

    # Returns the path where the Pod with the given name is stored, taking into
    # account whether the Pod is locally sourced.
    #
    # @param  [String] name
    #         The name of the Pod.
    #
    # @return [Pathname] the path of the Pod.
    #
    def pod_dir(name)
      root_name = Specification.root_name(name)
      if local?(root_name)
        Pathname.new(development_pods[root_name].dirname)
      else
        sources_root + root_name
      end
    end

    # Returns true if the path as originally specified was absolute.
    #
    # @param  [String] name
    #
    # @return [Bool] true if originally absolute
    #
    def local_path_was_absolute?(name)
      @pods_with_absolute_path.include? name
    end

    # @return [Pathname] The directory where headers are stored.
    #
    def headers_root
      root + 'Headers'
    end

    # @return [Pathname] The directory where the downloaded sources of
    #         the Pods are stored.
    #
    def sources_root
      root
    end

    # @return [Pathname] the path for the directory where the
    #         specifications are stored.
    #
    def specifications_root
      root + 'Local Podspecs'
    end

    # @return [Pathname] The directory where the files generated by
    #         CocoaPods to support the umbrella targets are stored.
    #
    def target_support_files_root
      root + 'Target Support Files'
    end

    #-------------------------------------------------------------------------#

    public

    # @!group Specification store

    # Returns the specification for the Pod with the given name.
    #
    # @param  [String] name
    #         the name of the Pod for which the specification is requested.
    #
    # @return [Specification] the specification if the file is found.
    #
    def specification(name)
      if file = specification_path(name)
        original_path = development_pods[name]
        Specification.from_file(original_path || file)
      end
    end

    # Returns the path of the specification for the Pod with the
    # given name, if one is stored.
    #
    # @param  [String] name
    #         the name of the Pod for which the podspec file is requested.
    #
    # @return [Pathname] the path or nil.
    # @return [Nil] if the podspec is not stored.
    #
    def specification_path(name)
      name = Specification.root_name(name)
      path = specifications_root + "#{name}.podspec"
      if path.exist?
        path
      else
        path = specifications_root + "#{name}.podspec.json"
        if path.exist?
          path
        end
      end
    end

    # Stores a specification in the `Local Podspecs` folder.
    #
    # @param  [String] name
    #         the name of the pod
    #
    # @param  [String, Pathname] podspec
    #         The contents of the specification (String) or the path to a
    #         podspec file (Pathname).
    #
    # @return [void]
    #
    #
    def store_podspec(name, podspec, _external_source = false, json = false)
      file_name = json ? "#{name}.podspec.json" : "#{name}.podspec"
      output_path = specifications_root + file_name
      output_path.dirname.mkpath
      if podspec.is_a?(String)
        output_path.open('w') { |f| f.puts(podspec) }
      else
        unless podspec.exist?
          raise Informative, "No podspec found for `#{name}` in #{podspec}"
        end
        FileUtils.copy(podspec, output_path)
      end

      Dir.chdir(podspec.is_a?(Pathname) ? File.dirname(podspec) : Dir.pwd) do
        spec = Specification.from_file(output_path)

        unless spec.name == name
          raise Informative, "The name of the given podspec `#{spec.name}` doesn't match the expected one `#{name}`"
        end
      end
    end

    #-------------------------------------------------------------------------#

    public

    # @!group Pods information

    # Marks a Pod as pre-downloaded
    #
    # @param  [String] name
    #         The name of the Pod.
    #
    # @return [void]
    #
    def store_pre_downloaded_pod(name)
      root_name = Specification.root_name(name)
      predownloaded_pods << root_name
    end

    # @return [Array<String>] The names of the pods that have been
    #         pre-downloaded from an external source.
    #
    attr_reader :predownloaded_pods

    # Checks if a Pod has been pre-downloaded by the resolver in order to fetch
    # the podspec.
    #
    # @param  [String] name
    #         The name of the Pod.
    #
    # @return [Bool] Whether the Pod has been pre-downloaded.
    #
    def predownloaded?(name)
      root_name = Specification.root_name(name)
      predownloaded_pods.include?(root_name)
    end

    #--------------------------------------#

    # Stores the local path of a Pod.
    #
    # @param  [String] name
    #         The name of the Pod.
    #
    # @param  [Hash] source
    #         The hash which contains the options as returned by the
    #         downloader.
    #
    # @return [void]
    #
    def store_checkout_source(name, source)
      root_name = Specification.root_name(name)
      checkout_sources[root_name] = source
    end

    # Removes the checkout source of a Pod.
    #
    # @param  [String] name
    #         The name of the Pod.
    #
    # @return [void]
    #
    def remove_checkout_source(name)
      root_name = Specification.root_name(name)
      checkout_sources.delete(root_name)
    end

    # @return [Hash{String=>Hash}] The options necessary to recreate the exact
    #         checkout of a given Pod grouped by its name.
    #
    attr_reader :checkout_sources

    #--------------------------------------#

    # Stores the local path of a Pod.
    #
    # @param  [String] name
    #         The name of the Pod.
    #
    # @param  [Pathname, String] path
    #         The path to the local Podspec
    #
    # @param  [Bool] was_absolute
    #         True if the specified local path was absolute.
    #
    # @return [void]
    #
    def store_local_path(name, path, was_absolute = false)
      root_name = Specification.root_name(name)
      path = Pathname.new(path) unless path.is_a?(Pathname)
      development_pods[root_name] = path
      @pods_with_absolute_path << root_name if was_absolute
    end

    # @return [Hash{String=>Pathname}] The path of the Pods' podspecs with a local source
    #         grouped by their root name.
    #
    # @todo   Rename (e.g. `pods_with_local_path`)
    #
    attr_reader :development_pods

    # Checks if a Pod is locally sourced?
    #
    # @param  [String] name
    #         The name of the Pod.
    #
    # @return [Bool] Whether the Pod is locally sourced.
    #
    def local?(name)
      !local_podspec(name).nil?
    end

    # @param  [String] name
    #         The name of a locally specified Pod
    #
    # @return [Pathname] Path to the local Podspec of the Pod
    #
    def local_podspec(name)
      root_name = Specification.root_name(name)
      if path = development_pods[root_name]
        Pathname.new(path)
      end
    end

    #-------------------------------------------------------------------------#

    public

    # @!group Pods Helpers

    # Creates the file accessors for the given Pod Targets.
    #
    # @param [Array<PodTarget>] pod_targets
    #                           The Pod Targets to create file accessors for.
    #
    def create_file_accessors(pod_targets)
      pod_targets.each do |pod_target|
        pod_root = pod_dir(pod_target.root_spec.name)
        path_list = PathList.new(pod_root)
        file_accessors = pod_target.specs.map do |spec|
          FileAccessor.new(path_list, spec.consumer(pod_target.platform))
        end
        pod_target.file_accessors ||= []
        pod_target.file_accessors.concat(file_accessors)
      end
    end

    #-------------------------------------------------------------------------#
  end
end
