# 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 #:nodoc:
  module Shell
    include Extension

    class << self
      def providers
        @providers ||= []
      end

      def select_by_lang(lang)
        fail 'Unable to define shell task for nil language' if lang.nil?
        providers.detect { |e| e.languages.nil? ? false : e.languages.include?(lang.to_sym) }
      end

      alias_method :select, :select_by_lang

      def select_by_name(name)
        fail 'Unable to define run task for nil' if name.nil?
        providers.detect { |e| e.to_sym == name.to_sym }
      end

      def define_task(project, name, provider = nil)
        ShellTask.define_task(name).tap do |t|
          t.send(:associate_with, project)
          t.enhance([project.compile]) do |t|
            # double-enhance to execute the provider last
            t.enhance { |t| t.run }
          end
          t.using provider.to_sym if provider
        end
      end
    end

    first_time do
      Project.local_task 'shell'

      providers.each { |provider| Project.local_task "shell:#{provider.to_sym}" }
    end

    before_define(:shell => :compile) do |project|
      define_task(project, "shell")
      providers.each { |provider| define_task(project, "shell:#{provider.to_sym}", provider) }
    end

    after_define(:shell => :compile) do |project|
      unless project.shell.provider
        provider = providers.find { |p| p.languages.include? project.compile.language if p.languages }
        if provider
          project.shell.using provider.to_sym
          project.shell.with project.test.compile.dependencies
        end
      end
    end

    # Base class for any shell provider.
    class Base
      attr_reader :project # :nodoc:

      class << self
        attr_accessor :shell_name, :languages

        def specify(options)
          @shell_name ||= options[:name]
          @languages ||= options[:languages]
        end

        def to_sym
          @shell_name || name.split('::').last.downcase.to_sym
        end
      end

      def initialize(project)
        @project = project
      end

      def launch(task)
        fail 'Not implemented'
      end

    end

    class ShellTask < Rake::Task
      attr_reader :project # :nodoc:

      # Classpath dependencies.
      attr_accessor :classpath

      # Returns the run options.
      attr_reader :options

      # Underlying shell provider
      attr_reader :provider

      def initialize(*args) # :nodoc:
        super
        @options = {}
        @classpath = []
      end

      # :call-seq:
      #   with(*artifacts) => self
      #
      # Adds files and artifacts as classpath dependencies, and returns self.
      def with(*specs)
        @classpath |= Buildr.artifacts(specs.flatten).uniq
        self
      end

      # :call-seq:
      #   using(options) => self
      #
      # Sets the run options from a hash and returns self.
      #
      # For example:
      #   shell.using :properties => {'foo' => 'bar'}
      #   shell.using :bsh
      def using(*args)
        if Hash === args.last
          args.pop.each { |key, value| @options[key.to_sym] = value }
        end

        until args.empty?
          new_shell = Shell.select_by_name(args.pop)
          @provider = new_shell.new(project) unless new_shell.nil?
        end

        self
      end

      def run
        fail "No shell provider defined in project '#{project.name}' for language '#{project.compile.language.inspect}'" unless provider
        provider.launch(self)
      end

      def prerequisites #:nodoc:
        super + classpath
      end

      def java_args
        @options[:java_args] || (ENV['JAVA_OPTS'] || ENV['JAVA_OPTIONS']).to_s.split
      end

      def properties
        @options[:properties] || {}
      end

    private
      def associate_with(project)
        @project ||= project
      end

    end

    # :call-seq:
    #   shell(&block) => ShellTask
    #
    # This method returns the project's shell task. It also accepts a block to be executed
    # when the shell task is invoked.
    def shell(&block)
      task('shell').tap do |t|
        t.enhance &block if block
      end
    end
  end

  class Project #:nodoc:
    include Shell
  end
end
