module Pod
  class Installer

    # Controller class responsible of creating and configuring the static
    # library target in Pods project. It also creates the support file needed
    # by the target.
    #
    class TargetInstaller

      # @return [Sandbox] sandbox the sandbox where the support files should
      #         be generated.
      #
      attr_reader :sandbox

      # @return [Library] The library whose target needs to be generated.
      #
      attr_reader :library

      # @param  [Project] project @see project
      # @param  [Library] library @see library
      #
      def initialize(sandbox, library)
        @sandbox = sandbox
        @library = library
      end

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

      private

      # @!group Installation steps

      # Adds the target for the library to the Pods project with the
      # appropriate build configurations.
      #
      # @note   The `PODS_HEADERS_SEARCH_PATHS` overrides the xcconfig.
      #
      # @todo   CocoaPods 0.16 used to add the build configurations to the build
      #         configuration list of the project (`root object`) as well with
      #         an empty build settings. This behaviour was changed in 0.17.
      #         Restore if needed.
      #
      # @return [void]
      #
      def add_target
        name = library.label
        platform = library.platform.name
        deployment_target = library.platform.deployment_target.to_s
        @target = project.new_target(:static_library, name, platform, deployment_target)

        settings = {}
        if library.platform.requires_legacy_ios_archs?
          settings['ARCHS'] = "armv6 armv7"
        end

        @target.build_settings('Debug').merge!(settings)
        @target.build_settings('Release').merge!(settings)

        library.user_build_configurations.each do |bc_name, type|
          unless @target.build_configurations.map(&:name).include?(bc_name)
            build_config = project.new(Xcodeproj::Project::XCBuildConfiguration)
            build_config.name = bc_name
            settings = @target.build_settings(type.to_s.capitalize).dup
            build_config.build_settings = settings
            target.build_configurations << build_config
          end
        end
      end

      # Creates the group that holds the references to the support files
      # generated by this installer.
      #
      # @return [void]
      #
      def create_suport_files_group
        @support_files_group = project.support_files_group.new_group(library.name)
      end

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

      # Generates a dummy source file for each target so libraries that contain
      # only categories build.
      #
      # @return [void]
      #
      def create_dummy_source
        path = library.dummy_source_path
        UI.message "- Generating dummy source file at #{UI.path(path)}" do
          generator = Generator::DummySource.new(library.label)
          generator.save_as(path)
          file_reference = add_file_to_support_group(path)
          target.source_build_phase.add_file_reference(file_reference)
        end
      end

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

      # @return [PBXNativeTarget] the target generated by the installation
      #         process.
      #
      # @note   Generated by the {#add_target} step.
      #
      attr_reader :target

      # @!group Private helpers.

      # @return [Project] the Pods project of the sandbox.
      #
      def project
        sandbox.project
      end

      # @return [TargetDefinition] the target definition of the library.
      #
      def target_definition
        library.target_definition
      end

      # @return [PBXGroup] the group where the file references to the support
      #         files should be stored.
      #
      attr_reader :support_files_group

      # Adds a reference to the given file in the support group of this target.
      #
      # @param  [Pathname] path
      #         The path of the file to which the reference should be added.
      #
      # @return [PBXFileReference] the file reference of the added file.
      #
      def add_file_to_support_group(path)
        relative_path = path.relative_path_from(sandbox.root)
        support_files_group.new_file(relative_path)
      end

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

    end
  end
end

