# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with this
# work for additional information regarding copyright ownership. The ASF
# licenses this file to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under
# the License.

module Buildr
  # Initial support for JaCoCo coverage reports.
  # WARNING: Experimental and may change radically.
  module JaCoCo
    class << self
      VERSION = '0.5.10.201208310627'

      def version
        @version || Buildr.settings.build['jacoco'] || VERSION
      end

      def version=(value)
        @version = value
      end

      def agent_spec
        ["org.jacoco:org.jacoco.agent:jar:runtime:#{version}"]
      end

      def ant_spec
        [
          "org.jacoco:org.jacoco.report:jar:#{version}",
          "org.jacoco:org.jacoco.core:jar:#{version}",
          "org.jacoco:org.jacoco.ant:jar:#{version}",
          'asm:asm:jar:3.3.1',
          'asm:asm-commons:jar:3.3.1',
          'asm:asm-tree:jar:3.3.1'
        ]
      end
    end

    class Config

      attr_writer :enabled

      def enabled?
        @enabled.nil? ? true : @enabled
      end

      attr_writer :destfile

      def destfile
        @destfile || "#{self.report_dir}/jacoco.cov"
      end

      attr_writer :output

      def output
        @output || 'file'
      end

      attr_accessor :sessionid
      attr_accessor :address
      attr_accessor :port
      attr_accessor :classdumpdir
      attr_accessor :dumponexit
      attr_accessor :append
      attr_accessor :exclclassloader

      def includes
        @includes ||= []
      end

      def excludes
        @excludes ||= []
      end

      attr_writer :report_dir

      def report_dir
        @report_dir || project._(:reports, :jacoco)
      end

      attr_writer :generate_xml

      def generate_xml?
        @generate_xml.nil? ? false : @generate_xml
      end

      attr_writer :xml_output_file

      def xml_output_file
        @xml_output_file || "#{self.report_dir}/jacoco.xml"
      end

      attr_writer :generate_html

      def generate_html?
        @generate_html.nil? ? false : @generate_html
      end

      attr_writer :html_output_directory

      def html_output_directory
        @html_output_directory || "#{self.report_dir}/jacoco"
      end

      protected

      def initialize(project)
        @project = project
      end

      attr_reader :project

    end

    module ProjectExtension
      include Extension

      def jacoco
        @jacoco ||= Buildr::JaCoCo::Config.new(project)
      end

      after_define do |project|
        unless project.test.compile.target.nil? || !project.jacoco.enabled?
          project.test.setup do
            agent_jar = Buildr.artifacts(Buildr::JaCoCo.agent_spec).each(&:invoke).map(&:to_s).join('')
            options = []
            ["destfile",
             "append",
             "exclclassloader",
             "sessionid",
             "dumponexit",
             "output",
             "address",
             "port",
             "classdumpdir"].each do |option|
              value = project.jacoco.send(option.to_sym)
              options << "#{option}=#{value}" unless value.nil?
            end
            options << "includes=#{project.jacoco.includes.join(':')}" unless project.jacoco.includes.empty?
            options << "excludes=#{project.jacoco.excludes.join(':')}" unless project.jacoco.excludes.empty?

            agent_config = "-javaagent:#{agent_jar}=#{options.join(',')}"
            project.test.options[:java_args] = (project.test.options[:java_args] || []) + [agent_config]
          end
          namespace 'jacoco' do
            if project.jacoco.generate_xml?
              desc "Generate JaCoCo reports."
              task 'reports' do
                Buildr.ant "jacoco" do |ant|
                  ant.taskdef(:resource => "org/jacoco/ant/antlib.xml") do |ant|
                    ant.classpath :path => Buildr.artifacts(Buildr::JaCoCo.ant_spec).each(&:invoke).map(&:to_s).join(File::PATH_SEPARATOR)
                  end
                  ant.report do |ant|
                    ant.executiondata do |ant|
                      ant.file :file => project.jacoco.destfile
                    end

                    ant.structure(:name => project.name) do |ant|
                      if project.compile.target
                        ant.classfiles do |ant|
                          ant.fileset :dir => project.compile.target
                        end
                      end
                      ant.sourcefiles(:encoding => "UTF-8") do |ant|
                        project.compile.sources.each do |path|
                          ant.fileset :dir => path.to_s
                        end
                      end
                    end

                    ant.xml :destfile => project.jacoco.xml_output_file if project.jacoco.generate_xml?
                    ant.html :destdir => project.jacoco.html_output_directory if project.jacoco.generate_html?
                  end
                end
              end
            end
          end
        end
      end
      namespace 'jacoco' do
        desc "Generate JaCoCo reports."
        task 'report' do
          Buildr.ant "jacoco" do |ant|
            ant.taskdef(:resource => "org/jacoco/ant/antlib.xml") do |ant|
              ant.classpath :path => Buildr.artifacts(Buildr::JaCoCo.ant_spec).each(&:invoke).map(&:to_s).join(File::PATH_SEPARATOR)
            end
            ant.report do |ant|
              ant.executiondata do |ant|
                Buildr.projects.each do |project|
                  ant.fileset :file=>project.jacoco.destfile if File.exist?(project.jacoco.destfile)
                end
              end

              ant.structure(:name => "Jacoco Report") do |ant|
                ant.classfiles do |ant|
                  Buildr.projects.map(&:compile).map(&:target).flatten.map(&:to_s).each do |src|
                    ant.fileset :dir=>src.to_s if File.exist?(src)
                  end
                end
                ant.sourcefiles(:encoding => "UTF-8") do |ant|
                  Buildr.projects.map(&:compile).map(&:sources).flatten.map(&:to_s).each do |src|
                    ant.fileset :dir=>src.to_s if File.exist?(src)
                  end
                end
              end

              ant.html :destdir => "reports/jacoco"
              ant.xml :destfile => "reports/jacoco/jacoco.xml"
              ant.csv :destfile => "reports/jacoco/jacoco.csv"
            end
          end
        end
      end
    end
  end
end

class Buildr::Project
  include Buildr::JaCoCo::ProjectExtension
end
