module Pod
  # Stores the information relative to the target used to compile a single Pod.
  # A pod can have one or more activated spec/subspecs.
  #
  class PodTarget < Target
    # @return [Array<Specification>] the spec and subspecs for the target.
    #
    attr_reader :specs

    # @return [Array<TargetDefinition>] the target definitions of the Podfile
    #         that generated this target.
    #
    attr_reader :target_definitions

    # @return [HeadersStore] the header directory for the target.
    #
    attr_reader :build_headers

    # @return [String] used as suffix in the label
    #
    # @note This affects the value returned by #configuration_build_dir
    #       and accessors relying on this as #build_product_path.
    #
    attr_reader :scope_suffix

    # @return [Array<PodTarget>] the targets that this target has a dependency
    #         upon.
    #
    attr_accessor :dependent_targets

    # @return [Array<PodTarget>] the targets that this target has a test dependency
    #         upon.
    #
    attr_accessor :test_dependent_targets

    # return [Array<PBXNativeTarget>] the test target generated in the Pods project for
    #         this library or `nil` if there is no test target created.
    #
    attr_accessor :test_native_targets

    # @param [Array<Specification>] specs @see #specs
    # @param [Array<TargetDefinition>] target_definitions @see #target_definitions
    # @param [Sandbox] sandbox @see #sandbox
    # @param [String] scope_suffix @see #scope_suffix
    #
    def initialize(specs, target_definitions, sandbox, scope_suffix = nil)
      raise "Can't initialize a PodTarget without specs!" if specs.nil? || specs.empty?
      raise "Can't initialize a PodTarget without TargetDefinition!" if target_definitions.nil? || target_definitions.empty?
      raise "Can't initialize a PodTarget with only abstract TargetDefinitions" if target_definitions.all?(&:abstract?)
      raise "Can't initialize a PodTarget with an empty string scope suffix!" if scope_suffix == ''
      super()
      @specs = specs
      @target_definitions = target_definitions
      @sandbox = sandbox
      @scope_suffix = scope_suffix
      @build_headers  = Sandbox::HeadersStore.new(sandbox, 'Private')
      @file_accessors = []
      @resource_bundle_targets = []
      @test_resource_bundle_targets = []
      @test_native_targets = []
      @dependent_targets = []
      @test_dependent_targets = []
      @build_config_cache = {}
    end

    # @param [Hash{Array => PodTarget}] cache
    #        the cached PodTarget for a previously scoped (specs, target_definition)
    # @return [Array<PodTarget>] a scoped copy for each target definition.
    #
    def scoped(cache = {})
      target_definitions.map do |target_definition|
        cache_key = [specs, target_definition]
        if cache[cache_key]
          cache[cache_key]
        else
          target = PodTarget.new(specs, [target_definition], sandbox, target_definition.label)
          target.file_accessors = file_accessors
          target.user_build_configurations = user_build_configurations
          target.native_target = native_target
          target.archs = archs
          target.dependent_targets = dependent_targets.flat_map { |pt| pt.scoped(cache) }.select { |pt| pt.target_definitions == [target_definition] }
          target.host_requires_frameworks = host_requires_frameworks
          cache[cache_key] = target
        end
      end
    end

    # @return [String] the label for the target.
    #
    def label
      if scope_suffix.nil? || scope_suffix[0] == '.'
        "#{root_spec.name}#{scope_suffix}"
      else
        "#{root_spec.name}-#{scope_suffix}"
      end
    end

    # @return [String] the Swift version for the target. If the pod author has provided a swift version
    #                  then that is the one returned, otherwise the Swift version is determined by the user
    #                  targets that include this pod target.
    #
    def swift_version
      root_spec.swift_version || target_definitions.map(&:swift_version).compact.uniq.first
    end

    # @note   The deployment target for the pod target is the maximum of all
    #         the deployment targets for the current platform of the target
    #         (or the minimum required to support the current installation
    #         strategy, if higher).
    #
    # @return [Platform] the platform for this target.
    #
    def platform
      @platform ||= begin
        platform_name = target_definitions.first.platform.name
        default = Podfile::TargetDefinition::PLATFORM_DEFAULTS[platform_name]
        deployment_target = specs.map do |spec|
          Version.new(spec.deployment_target(platform_name) || default)
        end.max
        if platform_name == :ios && requires_frameworks?
          minimum = Version.new('8.0')
          deployment_target = [deployment_target, minimum].max
        end
        Platform.new(platform_name, deployment_target)
      end
    end

    # @visibility private
    #
    attr_writer :platform

    # @return [Podfile] The podfile which declares the dependency.
    #
    def podfile
      target_definitions.first.podfile
    end

    # @return [String] The name to use for the source code module constructed
    #         for this target, and which will be used to import the module in
    #         implementation source files.
    #
    def product_module_name
      root_spec.module_name
    end

    # @return [Array<Sandbox::FileAccessor>] the file accessors for the
    #         specifications of this target.
    #
    attr_accessor :file_accessors

    # @return [Array<PBXNativeTarget>] the resource bundle targets belonging
    #         to this target.
    attr_reader :resource_bundle_targets

    # @return [Array<PBXNativeTarget>] the resource bundle test targets belonging
    #         to this target.
    attr_reader :test_resource_bundle_targets

    # @return [Bool] Whether or not this target should be build.
    #
    # A target should not be build if it has no source files.
    #
    def should_build?
      return @should_build if defined? @should_build
      @should_build = begin
        source_files = file_accessors.flat_map(&:source_files)
        source_files -= file_accessors.flat_map(&:headers)
        !source_files.empty? || contains_script_phases?
      end
    end

    # @return [Array<Specification::Consumer>] the specification consumers for
    #         the target.
    #
    def spec_consumers
      specs.map { |spec| spec.consumer(platform) }
    end

    # @return [Boolean] Whether the target uses Swift code.
    #
    def uses_swift?
      return @uses_swift if defined? @uses_swift
      @uses_swift = begin
        file_accessors.any? do |file_accessor|
          file_accessor.source_files.any? { |sf| sf.extname == '.swift' }
        end
      end
    end

    # @return [Array<Hash{Symbol=>String}>] An array of hashes where each hash represents a single script phase.
    #
    def script_phases
      spec_consumers.map(&:script_phases).flatten
    end

    # @return [Boolean] Whether the target contains any script phases.
    #
    def contains_script_phases?
      !script_phases.empty?
    end

    # @return [Hash{Array => Specification}] a hash where the keys are the test native targets and the value
    #         an array of all the test specs associated with this native target.
    #
    def test_specs_by_native_target
      test_specs.group_by { |test_spec| native_target_for_spec(test_spec) }
    end

    # @return [Boolean] Whether the target has any tests specifications.
    #
    def contains_test_specifications?
      specs.any?(&:test_specification?)
    end

    # @return [Array<Specification>] All of the test specs within this target.
    #
    def test_specs
      specs.select(&:test_specification?)
    end

    # @return [Array<Specification>] All of the non test specs within this target.
    #
    def non_test_specs
      specs.reject(&:test_specification?)
    end

    # @return [Array<Symbol>] All of the test supported types within this target.
    #
    def supported_test_types
      test_specs.map(&:test_type).uniq
    end

    # Returns the framework paths associated with this target. By default all paths include the framework paths
    # that are part of test specifications.
    #
    # @param  [Boolean] include_test_spec_paths
    #         Whether to include framework paths from test specifications or not.
    #
    # @return [Array<Hash{Symbol => [String]}>] The vendored and non vendored framework paths
    #         this target depends upon.
    #
    def framework_paths(include_test_spec_paths = true)
      @framework_paths ||= {}
      return @framework_paths[include_test_spec_paths] if @framework_paths.key?(include_test_spec_paths)
      @framework_paths[include_test_spec_paths] = begin
        accessors = file_accessors
        accessors = accessors.reject { |a| a.spec.test_specification? } unless include_test_spec_paths
        frameworks = []
        accessors.flat_map(&:vendored_dynamic_artifacts).map do |framework_path|
          relative_path_to_sandbox = framework_path.relative_path_from(sandbox.root)
          framework = { :name => framework_path.basename.to_s,
                        :input_path => "${PODS_ROOT}/#{relative_path_to_sandbox}",
                        :output_path => "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/#{framework_path.basename}" }
          # Until this can be configured, assume the dSYM file uses the file name as the framework.
          # See https://github.com/CocoaPods/CocoaPods/issues/1698
          dsym_name = "#{framework_path.basename}.dSYM"
          dsym_path = Pathname.new("#{framework_path.dirname}/#{dsym_name}")
          if dsym_path.exist?
            framework[:dsym_name] = dsym_name
            framework[:dsym_input_path] = "${PODS_ROOT}/#{relative_path_to_sandbox}.dSYM"
            framework[:dsym_output_path] = "${DWARF_DSYM_FOLDER_PATH}/#{dsym_name}"
          end
          frameworks << framework
        end
        if should_build? && requires_frameworks? && !static_framework?
          frameworks << { :name => product_name,
                          :input_path => build_product_path('${BUILT_PRODUCTS_DIR}'),
                          :output_path => "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/#{product_name}" }
        end
        frameworks
      end
    end

    # Returns the resource paths associated with this target. By default all paths include the resource paths
    # that are part of test specifications.
    #
    # @param  [Boolean] include_test_spec_paths
    #         Whether to include resource paths from test specifications or not.
    #
    # @return [Array<String>] The resource and resource bundle paths this target depends upon.
    #
    def resource_paths(include_test_spec_paths = true)
      @resource_paths ||= {}
      return @resource_paths[include_test_spec_paths] if @resource_paths.key?(include_test_spec_paths)
      @resource_paths[include_test_spec_paths] = begin
        accessors = file_accessors
        accessors = accessors.reject { |a| a.spec.test_specification? } unless include_test_spec_paths
        resource_paths = accessors.flat_map do |accessor|
          accessor.resources.flat_map { |res| "${PODS_ROOT}/#{res.relative_path_from(sandbox.project.path.dirname)}" }
        end
        resource_bundles = accessors.flat_map do |accessor|
          prefix = Generator::XCConfig::XCConfigHelper::CONFIGURATION_BUILD_DIR_VARIABLE
          prefix = configuration_build_dir unless accessor.spec.test_specification?
          accessor.resource_bundles.keys.map { |name| "#{prefix}/#{name.shellescape}.bundle" }
        end
        resource_paths + resource_bundles
      end
    end

    # Returns the corresponding native target to use based on the provided specification.
    # This is used to figure out whether to add a source file into the library native target or any of the
    # test native targets.
    #
    # @param  [Specification] spec
    #         The specification to base from in order to find the native target.
    #
    # @return [PBXNativeTarget] the native target to use or `nil` if none is found.
    #
    def native_target_for_spec(spec)
      return native_target unless spec.test_specification?
      test_native_targets.find do |native_target|
        native_target.symbol_type == product_type_for_test_type(spec.test_type)
      end
    end

    # Returns the corresponding native product type to use given the test type.
    # This is primarily used when creating the native targets in order to produce the correct test bundle target
    # based on the type of tests included.
    #
    # @param  [Symbol] test_type
    #         The test type to map to provided by the test specification DSL.
    #
    # @return [Symbol] The native product type to use.
    #
    def product_type_for_test_type(test_type)
      case test_type
      when :unit
        :unit_test_bundle
      else
        raise Informative, "Unknown test type `#{test_type}`."
      end
    end

    # Returns the corresponding test type given the product type.
    #
    # @param  [Symbol] product_type
    #         The product type to map to a test type.
    #
    # @return [Symbol] The native product type to use.
    #
    def test_type_for_product_type(product_type)
      case product_type
      when :unit_test_bundle
        :unit
      else
        raise Informative, "Unknown product type `#{product_type}`."
      end
    end

    # @return [Specification] The root specification for the target.
    #
    def root_spec
      specs.first.root
    end

    # @return [String] The name of the Pod that this target refers to.
    #
    def pod_name
      root_spec.name
    end

    # @param  [String] bundle_name
    #         The name of the bundle product, which is given by the +spec+.
    #
    # @return [String] The derived name of the resource bundle target.
    #
    def resources_bundle_target_label(bundle_name)
      "#{label}-#{bundle_name}"
    end

    # @param  [Symbol] test_type
    #         The test type to use for producing the test label.
    #
    # @return [String] The derived name of the test target.
    #
    def test_target_label(test_type)
      "#{label}-#{test_type.capitalize}-Tests"
    end

    # @param  [Symbol] test_type
    #         The test type to use for producing the test label.
    #
    # @return [String] The label of the app host label to use given the platform and test type.
    #
    def app_host_label(test_type)
      "AppHost-#{Platform.string_name(platform.symbolic_name)}-#{test_type.capitalize}-Tests"
    end

    # @param  [Symbol] test_type
    #         The test type this embed frameworks script path is for.
    #
    # @return [Pathname] The absolute path of the copy resources script for the given test type.
    #
    def copy_resources_script_path_for_test_type(test_type)
      support_files_dir + "#{test_target_label(test_type)}-resources.sh"
    end

    # @param  [Symbol] test_type
    #         The test type this embed frameworks script path is for.
    #
    # @return [Pathname] The absolute path of the embed frameworks script for the given test type.
    #
    def embed_frameworks_script_path_for_test_type(test_type)
      support_files_dir + "#{test_target_label(test_type)}-frameworks.sh"
    end

    # @return [Pathname] the absolute path of the prefix header file.
    #
    def prefix_header_path
      support_files_dir + "#{label}-prefix.pch"
    end

    # @param  [Symbol] test_type
    #         The test type prefix header path is for.
    #
    # @return [Pathname] the absolute path of the prefix header file for the given test type.
    #
    def prefix_header_path_for_test_type(test_type)
      support_files_dir + "#{test_target_label(test_type)}-prefix.pch"
    end

    # @return [Array<String>] The names of the Pods on which this target
    #         depends.
    #
    def dependencies
      spec_consumers.flat_map do |consumer|
        consumer.dependencies.map { |dep| Specification.root_name(dep.name) }
      end.uniq
    end

    # @return [Array<PodTarget>] the recursive targets that this target has a
    #         dependency upon.
    #
    def recursive_dependent_targets
      @recursive_dependent_targets ||= begin
        targets = dependent_targets.clone

        targets.each do |target|
          target.dependent_targets.each do |t|
            targets.push(t) unless t == self || targets.include?(t)
          end
        end

        targets
      end
    end

    # @return [Array<PodTarget>] the recursive targets that this target has a
    #         test dependency upon.
    #
    def recursive_test_dependent_targets
      @recursive_test_dependent_targets ||= begin
        targets = test_dependent_targets.clone

        targets.each do |target|
          target.test_dependent_targets.each do |t|
            targets.push(t) unless t == self || targets.include?(t)
          end
        end

        targets
      end
    end

    # @return [Array<PodTarget>] the canonical list of test dependent targets this target has a dependency upon.
    #         This includes the parent target as well as its transitive dependencies.
    #
    def all_test_dependent_targets
      [self, *recursive_dependent_targets, *recursive_test_dependent_targets].uniq
    end

    # Checks if the target should be included in the build configuration with
    # the given name of a given target definition.
    #
    # @param  [TargetDefinition] target_definition
    #         The target definition to check.
    #
    # @param  [String] configuration_name
    #         The name of the build configuration.
    #
    def include_in_build_config?(target_definition, configuration_name)
      key = [target_definition.label, configuration_name]
      if @build_config_cache.key?(key)
        return @build_config_cache[key]
      end

      whitelists = target_definition_dependencies(target_definition).map do |dependency|
        target_definition.pod_whitelisted_for_configuration?(dependency.name, configuration_name)
      end.uniq

      if whitelists.empty?
        @build_config_cache[key] = true
        true
      elsif whitelists.count == 1
        @build_config_cache[key] = whitelists.first
        whitelists.first
      else
        raise Informative, "The subspecs of `#{pod_name}` are linked to " \
          "different build configurations for the `#{target_definition}` " \
          'target. CocoaPods does not currently support subspecs across ' \
          'different build configurations.'
      end
    end

    # Checks if warnings should be inhibited for this pod.
    #
    # @return [Bool]
    #
    def inhibit_warnings?
      return @inhibit_warnings if defined? @inhibit_warnings
      whitelists = target_definitions.map do |target_definition|
        target_definition.inhibits_warnings_for_pod?(root_spec.name)
      end.uniq

      if whitelists.empty?
        @inhibit_warnings = false
        false
      elsif whitelists.count == 1
        @inhibit_warnings = whitelists.first
        whitelists.first
      else
        UI.warn "The pod `#{pod_name}` is linked to different targets " \
          "(#{target_definitions.map(&:label)}), which contain different " \
          'settings to inhibit warnings. CocoaPods does not currently ' \
          'support different settings and will fall back to your preference ' \
          'set in the root target definition.'
        podfile.root_target_definitions.first.inhibits_warnings_for_pod?(root_spec.name)
      end
    end

    # @param  [String] dir
    #         The directory (which might be a variable) relative to which
    #         the returned path should be. This must be used if the
    #         $CONFIGURATION_BUILD_DIR is modified.
    #
    # @return [String] The absolute path to the configuration build dir
    #
    def configuration_build_dir(dir = Generator::XCConfig::XCConfigHelper::CONFIGURATION_BUILD_DIR_VARIABLE)
      "#{dir}/#{label}"
    end

    # @param  [String] dir
    #         @see #configuration_build_dir
    #
    # @return [String] The absolute path to the build product
    #
    def build_product_path(dir = Generator::XCConfig::XCConfigHelper::CONFIGURATION_BUILD_DIR_VARIABLE)
      "#{configuration_build_dir(dir)}/#{product_name}"
    end

    # @return [String] The source path of the root for this target relative to `$(PODS_ROOT)`
    #
    def pod_target_srcroot
      "${PODS_ROOT}/#{sandbox.pod_dir(pod_name).relative_path_from(sandbox.root)}"
    end

    # @return [String] The version associated with this target
    #
    def version
      version = root_spec.version
      [version.major, version.minor, version.patch].join('.')
    end

    private

    # @param  [TargetDefinition] target_definition
    #         The target definition to check.
    #
    # @return [Array<Dependency>] The dependency of the target definition for
    #         this Pod. Return an empty array if the Pod is not a direct
    #         dependency of the target definition but the dependency of one or
    #         more Pods.
    #
    def target_definition_dependencies(target_definition)
      target_definition.dependencies.select do |dependency|
        Specification.root_name(dependency.name) == pod_name
      end
    end
  end
end
