require 'open4'

module Pod
  module Generator

    class Documentation
      def self.appledoc_installed?
        !`which appledoc`.strip.empty?
      end

      include Config::Mixin

      attr_reader :pod, :specification, :target_path, :options

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

      def name
        @specification.to_s
      end

      def company
        if @specification.authors
          @specification.authors.keys.sort.join(', ')
        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.absolute_source_files
      end

      def index_file
        @pod.chdir do
          Dir.glob('README*', File::FNM_CASEFOLD).first
        end
      end

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

      def generate_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']
        index = index_file
        options += ['--index-desc', index] if index
        options += spec_appledoc_options
      end

      def generate(install = false)
        unless self.class.appledoc_installed?
          puts "[!] Skipping documentation generation because appledoc can't be found." if config.verbose?
          return
        end

        options = generate_appledoc_options
        options += ['--output', @target_path.to_s]
        options += ['--keep-intermediate-files']
        options += install ? ['--create-docset'] : ['--no-create-docset']

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

      def appledoc(options)
        arguments = []
        arguments += options
        arguments += ['--print-settings'] if config.verbose?
        arguments += files.map(&:to_s)

        output = error = nil
        process = Open4.popen4('appledoc', *arguments) do |_, __, out, err|
          output, error = out.read, err.read
        end

        # appledoc exits with 1 if a warning was logged
        if process.exitstatus >= 2
          puts output, error
          raise "Appledoc encountered an error."
        end
      end
    end
  end
end
