require 'escape'
require 'active_support/core_ext/array/conversions'

module Pod
  module Generator

    class Documentation
      include Config::Mixin
      extend Executable

      executable :appledoc
      attr_reader :pod, :specification, :target_path, :options

      def initialize(pod)
        @pod = pod
        @specification = pod.top_specification
        @target_path = pod.sandbox.root + 'Documentation' + pod.name
        @options = @specification.documentation || {}
      end

      def name
        @specification.name + ' ' + @specification.version.to_s
      end

      def company
        if @specification.authors
          @specification.authors.keys.sort.to_sentence
        else
          'no-company'
        end
      end

      def copyright
        company
      end

      def description
        @specification.description || 'Generated by CocoaPods.'
      end

      def docs_id
        'org.cocoapods'
      end

      def files
        @pod.documentation_headers.map{ |f| f.relative_path_from(@pod.root).to_s }
      end

      def index_file
        @pod.readme_file.relative_path_from(@pod.root).to_s if @pod.readme_file
      end

      def spec_appledoc_options
        @options[:appledoc] || []
      end

      def appledoc_options
        options = [
          '--project-name', name,
          '--docset-desc', description,
          '--project-company', company,
          '--docset-copyright', copyright,
          '--company-id', docs_id,
          '--ignore', '.m',
          '--keep-undocumented-objects',
          '--keep-undocumented-members',
          '--keep-intermediate-files',
          '--exit-threshold', '2' # appledoc terminates with an exits status of 1 if a warning was logged
        ]
        options += ['--index-desc', index_file] if index_file
        options += spec_appledoc_options
      end

      def already_installed?
        index = spec_appledoc_options.index('--company-id')
        company_id = index ? spec_appledoc_options[index + 1] : docs_id
        Pathname.new(File.expand_path("~/Library/Developer/Shared/Documentation/DocSets/#{company_id}.#{name.gsub(/ /,'-')}.docset")).exist?
      end

      def generate(install = false)
        options = appledoc_options
        options += ['--output', @target_path.to_s]
        options += install ? ['--create-docset'] : ['--no-create-docset']
        # TODO: passing the files explicitly clutters output and chokes on very long list (AWSiOSSDK Spec).
        # It is possible to just pass the dir of the pod, however this would include other files like demo projects.
        options += files

        @target_path.mkpath
        @pod.chdir do
          appledoc Escape.shell_command(options)
        end

        if $?.exitstatus != 0
          puts "[!] Appledoc encountered an error (exitstatus: #{$?.exitstatus}), an update might be available to solve the issue." unless config.silent?
        end

      rescue Informative
        puts "[!] Skipping documentation generation because appledoc can't be found." if config.verbose?
      end
    end
  end
end
