# 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:

  # An ArtifactNamespace is a hierarchical dictionary used to manage ArtifactRequirements.
  # It can be used to have different artifact versions per project
  # or to allow users to select a version for addons or modules.
  #
  # Namespaces are opened using the Buildr.artifact_ns method, most important methods are:
  # [need]      Used to create a requirement on the namespace.
  # [use]       Set the artifact version to use for a requirement.
  # [values_at] Reference requirements by name.
  # [each]      Return each ArtifactRequirement in the namespace.
  # The method_missing method for instances provides some syntactic sugar to these.
  # See the following examples, and the methods for ArtifactRequirement.
  #
  # = Avoiding constant pollution on buildfile
  #
  # Each project has its own ArtifactNamespace inheriting the one from the
  # parent project up to the root namespace.
  #
  # Consider the following snippet, as project grows, each subproject
  # may need different artifact combinations and/or versions. Assigning
  # artifact specifications to constants can make it painful to maintain
  # their references even if using structs/hashes.
  #
  #   -- buildfile --
  #   SPRING = 'org.springframework:spring:jar:2.5'
  #   SPRING_OLD = 'org.springframework:spring:jar:1.0'
  #   LOGGING = ['comons-logging:commons-logging:jar:1.1.1',
  #              'log4j:log4j:jar:1.2.15']
  #   WL_LOGGING = artifact('bea:wlcommons-logging:jar:8.1').from('path/to/wlcommons-logging.jar')
  #   LOGGING_WEBLOGIC = ['comons-logging:commons-logging:jar:1.1.1',
  #                       WL_LOGGING]
  #   COMMONS = struct :collections => 'commons-collection:commons-collection:jar:3.1',
  #                    :net => 'commons-net:commons-net:jar:1.4.0'
  #
  #   define 'example1' do
  #     define 'one' do
  #       compile.with SPRING, LOGGING_WEBLOGIC, COMMONS
  #     end
  #     define 'two' do
  #       compile.with SPRING_OLD, LOGGING, COMMONS
  #     end
  #     define 'three' do
  #       compile.with "commons-collections:commons-collections:jar:2.2"
  #     end
  #   end
  #
  #
  # With ArtifactNamespace you can do some more advanced stuff, the following
  # annotated snipped could still be reduced if default artifact definitions were
  # loaded from yaml file (see section below and ArtifactNamespace.load).
  #
  #   -- buildfile --
  #   artifact_ns do |ns| # the current namespace (root if called outside a project)
  #     # default artifacts
  #     ns.spring = 'org.springframework:spring:jar:2.5'
  #     # default logger is log4j
  #     ns.logger = 'log4j:log4j:jar:1.2.15'
  #
  #     # create a sub namespace by calling the #ns method,
  #     # artifacts defined on the sub-namespace can be referenced by
  #     # name :commons_net or by calling commons.net
  #     ns.ns :commons, :net => 'commons-net:commons-net:jar:1.4.0',
  #                     :logging => 'comons-logging:commons-logging:jar:1.1.1'
  #
  #
  #     # When a child namespace asks for the :log artifact,
  #     # these artifacts will be searched starting from the :current namespace.
  #     ns.virtual :log, :logger, :commons_logging
  #   end
  #
  #   artifact_ns('example2:one') do |ns| # namespace for the one subproject
  #     ns.logger = artifact('bea:wlcommons-logging:jar:8.1').from('path/to/wlcommons-logging.jar')
  #   end
  #   artifact_ns('example2:two') do |ns|
  #     ns.spring = '1.0' # for project two use an older spring version (just for an example)
  #   end
  #   artifact_ns('example2:three').commons_collections = 2.2'
  #   artifact_ns('example2:four') do |ns|
  #     ns.beanutils = 'commons-beanutils:commons-beanutils:jar:1.5'        # just for this project
  #     ns.ns(:compilation).use :commons_logging, :beanutils, :spring       # compile time dependencies
  #     ns.ns(:testing).use :log, :beanutils, 'cglib:cglib-nodep:jar:2.1.3' # run time dependencies
  #   end
  #
  #   define 'example2' do
  #     define 'one' do
  #       compile.with :spring, :log, :commons # uses weblogic logging
  #     end
  #     define 'two' do
  #       compile.with :spring, :log, :commons # will take old spring
  #     end
  #     define 'three' do
  #       compile.with :commons_collections
  #       test.with artifact_ns('example2:two').spring # use spring from project two
  #     end
  #     define 'four' do
  #       compile.with artifact_ns.compilation
  #       test.with artifact_ns.testing
  #     end
  #     task(:down_them_all) do # again, just to fill this space with something ;)
  #       parent.projects.map(&method(:artifact_ns)).map(&:artifacts).map(&:invoke)
  #     end
  #   end
  #
  # = Loading from a yaml file (e. profiles.yaml)
  #
  # If your projects use lots of jars (after all we are using java ;) you may prefer
  # to have constant artifact definitions on an external file.
  # Doing so would allow an external tool (or future Buildr feature) to maintain
  # an artifacts.yaml for you.
  # An example usage is documented on the ArtifactNamespace.load method.
  #
  # = For addon/plugin writers & Customizing artifact versions
  #
  # Sometimes users would need to change the default artifact versions used by some
  # module, for example, the XMLBeans compiler needs this, because of compatibility
  # issues. Another example would be to select the groovy version to use on all our
  # projects so that Buildr modules requiring groovy jars can use user preferred versions.
  #
  # To meet this goal, an ArtifactNamespace allows to specify ArtifactRequirement objects.
  # In fact the only difference with the examples you have already seen is that requirements
  # have an associated VersionRequirement, so that each time a user tries to select a version,
  # buildr checks if it satisfies the requirements.
  #
  # Requirements are declared using the ArtifactNamespace#need method, but again,
  # syntactic sugar is provided by ArtifactNamespace#method_missing.
  #
  # The following example is taken from the XMLBeans compiler module.
  # And illustrates how addon authors should specify their requirements,
  # provide default versions, and document the namespace for users to customize.
  #
  #    module Buildr::XMLBeans
  #
  #       # You need to document this constant, giving users some hints
  #       # about when are (maybe some of) these artifacts used. I mean,
  #       # some modules, add jars to the Buildr classpath when its file
  #       # is required, you would need to tell your users, so that they
  #       # can open the namespace and specify their defaults. Of course
  #       # when the requirements are defined, buildr checks if any compatible
  #       # version has been already defined, if so, uses it.
  #       #
  #       # Some things here have been changed to illustrate their meaning.
  #       REQUIRES = ArtifactNamespace.for(self).tap do |ns|
  #
  #         # This jar requires a >2.0 version, default being 2.3.0
  #         ns.xmlbeans! 'org.apache.xmlbeans:xmlbeans:jar:2.3.0', '>2'
  #
  #         # Users can customize with Buildr::XMLBeans::REQUIRES.stax_api = '1.2'
  #         # This is a non-flexible requirement, only satisfied by version 1.0.1
  #         ns.stax_api! 'stax:stax-api:jar:1.0.1'
  #
  #         # This one is not part of XMLBeans, but is just another example
  #         # illustrating an `artifact requirement spec`.
  #
  #         ns.need " some_name ->  ar:ti:fact:3.2.5 ->  ( >2 & <4)"
  #
  #         # As you can see it's just an artifact spec, prefixed with
  #         # ' some_name -> ', this means users can use that name to
  #         # reference the requirement, also this string has a VersionRequirement
  #         # just after another ->.
  #       end
  #
  #       # The REQUIRES constant is an ArtifactNamespace instance,
  #       # that means we can use it directly. Note that calling
  #       # Buildr.artifact_ns would lead to the currently executing context,
  #       # not the one for this module.
  #       def use
  #         # test if user specified his own version, if so, we could perform some
  #         # functionallity based on this.
  #         REQUIRES.some_name.selected? # => false
  #
  #         REQUIRES.some_name.satisfied_by?('1.5') # => false
  #         puts REQUIRES.some_name.requirement     # => ( >2 & <4 )
  #
  #         REQUIRES.artifacts # get the Artifact tasks
  #       end
  #
  #    end
  #
  # A more advanced example using ArtifactRequirement listeners is included
  # in the artifact_namespace_spec.rb description for 'Extension using ArtifactNamespace'
  # That's it for addon writers, now, users can select their preferred version with
  # something like:
  #
  #    require 'buildr/xmlbeans'
  #    Buildr::XMLBeans::REQUIRES.xmlbeans = '2.2.0'
  #
  # More advanced stuff, if users really need to select an xmlbeans version
  # per project, they can do so letting :current (that is, the currently running
  # namespace) be parent of the REQUIRES namespace:
  #
  #    Buildr::XMLBeans::REQUIRES.parent = :current
  #
  # Now, provided that the compiler does not caches its artifacts, it will
  # select the correct version. (See the first section for how to select per project
  # artifacts).
  #
  #
  class ArtifactNamespace
    class << self
      # Forget all namespaces, create a new ROOT
      def clear
        @instances = nil
        remove_const(:ROOT) rescue nil
        const_set(:ROOT, new('root'))
      end

      # Differs from Artifact.to_hash in that 1) it does not choke when version isn't present
      # and 2) it assumes that if an artifact spec ends with a colon, e.g. "org.example:library:jdk5:"
      # it indicates the last segment ("jdk5") is a classifier.
      def to_hash(spec)
        if spec.respond_to?(:to_spec)
          to_hash spec.to_spec
        elsif Hash === spec
          return spec
        elsif String === spec || Symbol === spec
          spec = spec.to_s
          if spec[-1,1] == ':'
            group, id, type, classifier, *rest = spec.split(':').map { |part| part.empty? ? nil : part }
          else
            group, id, type, version, *rest = spec.split(':').map { |part| part.empty? ? nil : part }
            unless rest.empty?
              # Optional classifier comes before version.
              classifier, version = version, rest.shift
            end
          end
          fail "Expecting <group:id:type:version> or <group:id:type:classifier:version>, found <#{spec}>" unless rest.empty?
          { :group => group, :id => id, :type => type, :version => version, :classifier => classifier }.reject { |k,v| v == nil }
        else
          fail "Unexpected artifact spec: #{spec.inspect}"
        end
      end

      # Populate namespaces from a hash of hashes.
      # The following example uses the profiles yaml to achieve this.
      #
      #   -- profiles.yaml --
      #   development:
      #     artifacts:
      #       root:        # root namespace
      #         spring:     org.springframework:spring:jar:2.5
      #         groovy:     org.codehaus.groovy:groovy:jar:1.5.4
      #         logging:    # define a named group
      #           - log4j:log4j:jar:1.2.15
      #           - commons-logging:commons-logging:jar:1.1.1
      #
      #       # open Buildr::XMLBeans namespace
      #       Buildr::XMLBeans:
      #         xmlbeans: 2.2
      #
      #       # for subproject one:oldie
      #       one:oldie:
      #         spring:  org.springframework:spring:jar:1.0
      #
      #   -- buildfile --
      #   ArtifactNamespace.load(Buildr.settings.profile['artifacts'])
      def load(namespaces = {})
        namespaces.each_pair { |name, uses| instance(name).use(uses) }
      end

      # :call-seq:
      #   ArtifactNamespace.instance { |current_ns| ... } -> current_ns
      #   ArtifactNamespace.instance(name) { |ns| ... } -> ns
      #   ArtifactNamespace.instance(:current) { |current_ns| ... } -> current_ns
      #   ArtifactNamespace.instance(:root) { |root_ns| ... } -> root_ns
      #
      # Obtain an instance for the given name
      def instance(name = nil)
        case name
        when :root, 'root' then return ROOT
        when ArtifactNamespace then return name
        when Array then name = name.join(':')
        when Module, Project then name = name.name
        when :current, 'current', nil then
          task = Thread.current[:rake_chain]
          task = task.instance_variable_get(:@value) if task
          name = case task
                 when Project then task.name
                 when Rake::Task then task.scope.join(':')
                 when nil then Buildr.application.current_scope.join(':')
                 end
        end
        name = name.to_s
        if name.size == 0
          instance = ROOT
        else
          name = name.to_s
          @instances ||= Hash.new { |h, k| h[k] = new(k) }
          instance = @instances[name]
        end
        yield(instance) if block_given?
        instance
      end

      alias_method :[], :instance
      alias_method :for, :instance

      # :call-seq:
      #   ArtifactNamespace.root { |ns| ... } -> ns
      #
      # Obtain the root namespace, returns the ROOT constant
      def root
        yield ROOT if block_given?
        ROOT
      end
    end

    module DClone #:nodoc:
      def dclone
        clone = self.clone
        clone.instance_variables.each do |i|
          value = clone.instance_variable_get(i)
          value = value.dclone rescue
          clone.instance_variable_set(i, value)
        end
        clone
      end
    end

    class Registry < Hash #:nodoc:
      include DClone

      attr_accessor :parent
      def alias(new_name, old_name)
        new_name = new_name.to_sym
        old_name = old_name.to_sym
        if obj = get(old_name, true)
          self[new_name] = obj
          @aliases ||= []
          group = @aliases.find { |a| a.include?(new_name) }
          group.delete(new_name) if group
          group = @aliases.find { |a| a.include?(old_name) }
          @aliases << (group = [old_name]) unless group
          group << new_name unless group.include?(new_name)
        end
        obj
      end

      def aliases(name)
        return [] unless name
        name = name.to_sym
        ((@aliases ||= []).find { |a| a.include?(name) } || [name]).dup
      end

      def []=(key, value)
        return unless key
        super(key.to_sym, value)
      end

      def get(key, include_parent = nil)
        [].tap { |a| aliases(key).select { |n| a[0] = self[n] } }.first ||
          (include_parent && parent && parent.get(key, include_parent))
      end

      def keys(include_parent = nil)
        (super() | (include_parent && parent && parent.keys(include_parent) || [])).uniq
      end

      def values(include_parent = nil)
        (super() | (include_parent && parent && parent.values(include_parent) || [])).uniq
      end

      def key?(key, include_parent = nil)
        return false unless key
        super(key.to_sym) || (include_parent && parent && parent.key?(key, include_parent))
      end

      def delete(key, include_parent = nil)
        aliases(key).map {|n| super(n) } && include_parent && parent && parent.delete(key, include_parent)
      end
    end

    # An artifact requirement is an object that ActsAsArtifact and has
    # an associated VersionRequirement. It also knows the name (some times equal to the
    # artifact id) that is used to store it in an ArtifactNamespace.
    class ArtifactRequirement
      attr_accessor :version
      attr_reader :name, :requirement

      include DClone

      # Create a requirement from an `artifact requirement spec`.
      # This spec has three parts, separated by  ->
      #
      #     some_name ->  ar:ti:fact:3.2.5 ->  ( >2 & <4)
      #
      # As you can see it's just an artifact spec, prefixed with
      #     some_name ->
      # the :some_name symbol becomes this object's name and
      # is used to store it on an ArtifactNamespace.
      #
      #                   ar:ti:fact:3.2.5
      #
      # The second part is an artifact spec by itself, and specifies
      # all remaining attributes, the version of this spec becomes
      # the default version of this requirement.
      #
      # The last part consist of a VersionRequirement.
      #                                     ->  ( >2 & <4)
      #
      # VersionRequirement supports RubyGem's comparison operators
      # in adition to parens, logical and, logical or and negation.
      # See the docs for VersionRequirement for more info on operators.
      def initialize(spec)
        self.class.send :include, ActsAsArtifact unless ActsAsArtifact === self
        if ArtifactRequirement === spec
          copy_attrs(spec)
        else
          spec = requirement_hash(spec)
          apply_spec_no_validation(spec[:spec])
          self.name = spec[:name]
          @requirement = spec[:requirement]
          @version = @requirement.default if VersionRequirement.requirement?(@version)
        end
      end

      def apply_spec_no_validation(spec)
        spec = ArtifactNamespace.to_hash(spec)
        ActsAsArtifact::ARTIFACT_ATTRIBUTES.each { |key| instance_variable_set("@#{key}", spec[key]) }
        self
      end

      # Copy attributes from other to this object
      def copy_attrs(other)
        (ActsAsArtifact::ARTIFACT_ATTRIBUTES + [:name, :requirement]).each do |attr|
          value = other.instance_variable_get("@#{attr}")
          value = value.dup if value && !value.kind_of?(Numeric) && !value.kind_of?(Symbol)
          instance_variable_set("@#{attr}", value)
        end
      end

      def name=(name)
        @name = name.to_s
      end

      # Set a the requirement, this must be an string formatted for
      # VersionRequirement#create to parse.
      def requirement=(version_requirement)
        @requirement = VersionRequirement.create(version_requirement.to_s)
      end

      # Return a hash consisting of :name, :spec, :requirement
      def requirement_hash(spec = self)
        result = {}
        if String === spec
          parts = spec.split(/\s*->\s*/, 3).map(&:strip)
          case parts.size
          when 1
            result[:spec] = ArtifactNamespace.to_hash(parts.first)
          when 2
            if /^\w+$/ === parts.first
              result[:name] = parts.first
              result[:spec] = ArtifactNamespace.to_hash(parts.last)
            else
              result[:spec] = ArtifactNamespace.to_hash(parts.first)
              result[:requirement] = VersionRequirement.create(parts.last)
            end
          when 3
            result[:name] = parts.first
            result[:spec] = ArtifactNamespace.to_hash(parts[1])
            result[:requirement] = VersionRequirement.create(parts.last)
          end
        else
          result[:spec] = ArtifactNamespace.to_hash(spec)
        end
        result[:name] ||= result[:spec][:id].to_s.to_sym
        result[:requirement] ||= VersionRequirement.create(result[:spec][:version])
        result
      end

      # Test if this requirement is satisfied by an artifact spec.
      def satisfied_by?(spec)
        return false unless requirement
        spec = ArtifactNamespace.to_hash(spec)
        hash = to_spec_hash
        hash.delete(:version)
        version = spec.delete(:version)
        hash == spec && requirement.satisfied_by?(version)
      end

      # Has user selected a version for this requirement?
      def selected?
        @selected
      end

      def selected! #:nodoc:
        @selected = true
        @listeners.each { |l| l.call(self) } if @listeners
        self
      end

      def add_listener(&callback)
        (@listeners ||= []) << callback
      end

      # Return the Artifact object for the currently selected version
      def artifact
        ::Buildr.artifact(self)
      end

      # Format this requirement as an `artifact requirement spec`
      def to_requirement_spec
        result = to_spec
        result = "#{name} -> #{result}" if name
        result = "#{result} -> #{requirement}" if requirement
        result
      end

      def to_s #:nodoc:
        id ? to_requirement_spec : version
      end

      # Return an artifact spec without the version part.
      def unversioned_spec
        hash = to_spec_hash
        return nil if hash.values.compact.length <= 1
        if hash[:classifier]
          "#{hash[:group]}:#{hash[:id]}:#{hash[:type]}:#{hash[:classifier]}:"
        else
          "#{hash[:group]}:#{hash[:id]}:#{hash[:type]}"
        end
      end

      class << self
        def unversioned_spec(spec)
          hash = ArtifactNamespace.to_hash(spec)
          return nil if hash.values.compact.length <= 1
          if hash[:classifier]
            "#{hash[:group]}:#{hash[:id]}:#{hash[:type]}:#{hash[:classifier]}:"
          else
            "#{hash[:group]}:#{hash[:id]}:#{hash[:type]}"
          end
        end
      end
    end

    include DClone
    include Enumerable
    attr_reader :name

    def initialize(name = nil) #:nodoc:
      @name = name.to_s if name
    end
    clear

    def root
      yield ROOT if block_given?
      ROOT
    end

    # ROOT namespace has no parent
    def parent
      if root?
        nil
      elsif @parent.kind_of?(ArtifactNamespace)
        @parent
      elsif @parent
        ArtifactNamespace.instance(@parent)
      elsif name
        parent_name = name.gsub(/::?[^:]+$/, '')
        parent_name == name ? root : ArtifactNamespace.instance(parent_name)
      else
        root
      end
    end

    # Set the parent for the current namespace, except if it is ROOT
    def parent=(other)
      raise 'Cannot set parent of root namespace' if root?
      @parent = other
      @registry = nil
    end

    # Is this the ROOT namespace?
    def root?
      ROOT == self
    end

    # Create a named sub-namespace, sub-namespaces are themselves
    # ArtifactNamespace instances but cannot be referenced by
    # the Buildr.artifact_ns, ArtifactNamespace.instance methods.
    # Reference needs to be through this object using the given +name+
    #
    #   artifact_ns('foo').ns(:bar).need :thing => 'some:thing:jar:1.0'
    #   artifact_ns('foo').bar # => the sub-namespace 'foo.bar'
    #   artifact_ns('foo').bar.thing # => the some thing artifact
    #
    # See the top level ArtifactNamespace documentation for examples
    def ns(name, *uses, &block)
      name = name.to_sym
      sub = registry[name]
      if sub
        raise TypeError.new("#{name} is not a sub namespace of #{self}") unless sub.kind_of?(ArtifactNamespace)
      else
        sub = ArtifactNamespace.new("#{self.name}.#{name}")
        sub.parent = self
        registry[name] = sub
      end
      sub.use(*uses)
      yield sub if block_given?
      sub
    end

    # Test if a sub-namespace by the given name exists
    def ns?(name)
      sub = registry[name.to_sym]
      ArtifactNamespace === sub
    end

    # :call-seq:
    #   artifact_ns.need 'name -> org:foo:bar:jar:~>1.2.3 -> 1.2.5'
    #   artifact_ns.need :name => 'org.foo:bar:jar:1.0'
    #
    # Create a new ArtifactRequirement on this namespace.
    # ArtifactNamespace#method_missing provides syntactic sugar for this.
    def need(*specs)
      named = specs.flatten.inject({}) do |seen, spec|
        if Hash === spec && (spec.keys & ActsAsArtifact::ARTIFACT_ATTRIBUTES).empty?
          spec.each_pair do |name, spec|
            if Array === spec # a group
              seen[name] ||= spec.map { |s| ArtifactRequirement.new(s) }
            else
              artifact = ArtifactRequirement.new(spec)
              artifact.name = name
              seen[artifact.name] ||= artifact
            end
          end
        else
          artifact = ArtifactRequirement.new(spec)
          seen[artifact.name] ||= artifact
        end
        seen
      end
      named.each_pair do |name, artifact|
        if Array === artifact # a group
          artifact.each do |a|
            unvers = a.unversioned_spec
            previous = registry[unvers]
            if previous && previous.selected? && a.satisfied_by?(previous)
              a.version = previous.version
            end
            registry[unvers] = a
          end
          group(name, *(artifact.map { |a| a.unversioned_spec } + [{:namespace => self}]))
        else
          unvers = artifact.unversioned_spec
          previous = registry.get(unvers, true)
          if previous && previous.selected? && artifact.satisfied_by?(previous)
            artifact.version = previous.version
            artifact.selected!
          end
          registry[unvers] = artifact
          registry.alias name, unvers unless name.to_s[/^\s*$/]
        end
      end
      self
    end

    # :call-seq:
    #   artifact_ns.use 'name -> org:foo:bar:jar:1.2.3'
    #   artifact_ns.use :name => 'org:foo:bar:jar:1.2.3'
    #   artifact_ns.use :name => '2.5.6'
    #
    # First and second form are equivalent, the third is used when an
    # ArtifactRequirement has been previously defined with :name, so it
    # just selects the version.
    #
    # ArtifactNamespace#method_missing provides syntactic sugar for this.
    def use(*specs)
      named = specs.flatten.inject({}) do |seen, spec|
        if Hash === spec && (spec.keys & ActsAsArtifact::ARTIFACT_ATTRIBUTES).empty?
          spec.each_pair do |name, spec|
            if ArtifactNamespace === spec # create as subnamespace
              raise ArgumentError.new("Circular reference") if self == spec
              registry[name.to_sym] = spec
            elsif Numeric === spec || (String === spec && VersionRequirement.version?(spec))
              artifact = ArtifactRequirement.allocate
              artifact.name = name
              artifact.version = spec.to_s
              seen[artifact.name] ||= artifact
            elsif Symbol === spec
              self.alias name, spec
            elsif Array === spec # a group
              seen[name] ||= spec.map { |s| ArtifactRequirement.new(s) }
            else
              artifact = ArtifactRequirement.new(spec)
              artifact.name = name
              seen[artifact.name] ||= artifact
            end
          end
        else
          if Symbol === spec
            artifact = get(spec).dclone
          else
            artifact = ArtifactRequirement.new(spec)
          end
          seen[artifact.name] ||= artifact
        end
        seen
      end
      named.each_pair do |name, artifact|
        is_group = Array === artifact
        artifact = [artifact].flatten.map do |artifact|
          unvers = artifact.unversioned_spec
          previous = get(unvers, false) || get(name, false)
          if previous # have previous on current namespace
            if previous.requirement # we must satisfy the requirement
              if unvers
                satisfied = previous.satisfied_by?(artifact)
              else # we only have the version
                satisfied = previous.requirement.satisfied_by?(artifact.version)
              end
              raise "Unsatisfied dependency #{previous} " +
                "not satisfied by #{artifact}" unless satisfied
              previous.version = artifact.version # OK, set new version
              artifact = previous # use the same object for aliases
            else # not a requirement, set the new values
              unless artifact.id == previous.id && name != previous.name
                previous.copy_attrs(artifact)
                artifact = previous
              end
            end
          else
            if unvers.nil? && # we only have the version
                (previous = get(unvers, true, false, false))
              version = artifact.version
              artifact.copy_attrs(previous)
              artifact.version = version
            end
            artifact.requirement = nil
          end
          artifact.selected!
        end
        artifact = artifact.first unless is_group
        if is_group
          names = artifact.map do |art|
            unv = art.unversioned_spec
            registry[unv] = art
            unv
          end
          group(name, *(names + [{:namespace => self}]))
        elsif artifact.id
          unvers = artifact.unversioned_spec
          registry[name] = artifact
          registry.alias unvers, name
        else
          registry[name] = artifact
        end
      end
      self
    end

    # Like Hash#fetch
    def fetch(name, default = nil, &block)
      block ||= proc { raise IndexError.new("No artifact found by name #{name.inspect} in namespace #{self}") }
      real_name = name.to_s[/^[\w\-\.]+$/] ? name : ArtifactRequirement.unversioned_spec(name)
      get(real_name.to_sym) || default || block.call(name)
    end

    # :call-seq:
    #   artifact_ns[:name] -> ArtifactRequirement
    #   artifact_ns[:many, :names] -> [ArtifactRequirement]
    def [](*names)
      ary = values_at(*names)
      names.size == 1 ? ary.first : ary
    end

    # :call-seq:
    #   artifact_ns[:name] = 'some:cool:jar:1.0.2'
    #   artifact_ns[:name] = '1.0.2'
    #
    # Just like the use method
    def []=(*names)
      values = names.pop
      values = [values] unless Array === values
      names.each_with_index do |name, i|
        use name => (values[i] || values.last)
      end
    end

    # yield each ArtifactRequirement
    def each(&block)
      values.each(&block)
    end

    # return Artifact objects for each requirement
    def artifacts(*names)
      (names.empty? && values || values_at(*names)).map(&:artifact)
    end

    # Return all requirements for this namespace
    def values(include_parents = false, include_groups = true)
      seen, dict = {}, registry
      while dict
        dict.each do |k, v|
          v = v.call if v.respond_to?(:call)
          v = v.values if v.kind_of?(ArtifactNamespace)
          if Array === v && include_groups
            v.compact.each { |v| seen[v.name] = v unless seen.key?(v.name) }
          else
            seen[v.name] = v unless seen.key?(v.name)
          end
        end
        dict = include_parents ? dict.parent : nil
      end
      seen.values
    end

    # Return only the named requirements
    def values_at(*names)
      names.map do |name|
        catch :artifact do
          unless name.to_s[/^[\w\-\.]+$/]
            unvers = ArtifactRequirement.unversioned_spec(name)
            unless unvers.to_s == name.to_s
              req = ArtifactRequirement.new(name)
              reg = self
              while reg
                candidate = reg.send(:get, unvers, false, false, true)
                throw :artifact, candidate if req.satisfied_by?(candidate)
                reg = reg.parent
              end
            end
          end
          get(name.to_sym)
        end
      end
    end

    def key?(name, include_parents = false)
      name = ArtifactRequirement.unversioned_spec(name) unless name.to_s[/^[\w\-\.]+$/]
      registry.key?(name, include_parents)
    end

    def keys
      values.map(&:name)
    end

    def delete(name, include_parents = false)
      registry.delete(name, include_parents)
      self
    end

    def clear
      keys.each { |k| delete(k) }
    end

    # :call-seq:
    #   group :who, :me, :you
    #   group :them, :me, :you, :namespace => ns
    #
    # Create a virtual group on this namespace. When the namespace
    # is asked for the +who+ artifact, it's value is an array made from
    # the remaining names. These names are searched by default from the current
    # namespace.
    # Second form specified the starting namespace to search from.
    def group(group_name, *members)
      namespace = (Hash === members.last && members.pop[:namespace]) || :current
      registry[group_name] = lambda do
        artifacts = self.class[namespace].values_at(*members)
        artifacts = artifacts.first if members.size == 1
        artifacts
      end
      self
    end

    alias_method :virtual, :group

    # Create an alias for a named requirement.
    def alias(new_name, old_name)
      registry.alias(new_name, old_name) or
        raise NameError.new("Undefined artifact name: #{old_name}")
    end

    def to_s #:nodoc:
      name.to_s
    end

    # :call-seq:
    #   artifact_ns.cool_aid!('cool:aid:jar:2.3.4', '~>2.3') -> artifact_requirement
    #   artifact_ns.cool_aid = '2.3.5'
    #   artifact_ns.cool_aid  -> artifact_requirement
    #   artifact_ns.cool_aid? -> true | false
    #
    # First form creates an ArtifactRequirement on the namespace.
    # It is equivalent to providing a requirement_spec to the #need method:
    #   artifact_ns.need "cool_aid -> cool:aid:jar:2.3.4 -> ~>2.3"
    # the second argument is optional.
    #
    # Second form can be used to select an artifact version
    # and is equivalent to:
    #   artifact_ns.use :cool_aid => '1.0'
    #
    # Third form obtains the named ArtifactRequirement, can be
    # used to test if a named requirement has been defined.
    # It is equivalent to:
    #   artifact_ns.fetch(:cool_aid) { nil }
    #
    # Last form tests if the ArtifactRequirement has been defined
    # and a version has been selected for use.
    # It is equivalent to:
    #
    #   artifact_ns.has_cool_aid?
    #   artifact_ns.values_at(:cool_aid).flatten.all? { |a| a && a.selected? }
    #
    def method_missing(name, *args, &block)
      case name.to_s
      when /!$/ then
        name = $`.intern
        if args.size < 1 || args.size > 2
          raise ArgumentError.new("wrong number of arguments for #{name}!(spec, version_requirement?)")
        end
        need name => args.first
        get(name).tap { |r| r.requirement = args.last if args.size == 2 }
      when /=$/ then use $` => args.first
      when /\?$/ then
        name = $`.gsub(/^(has|have)_/, '').intern
        [get(name)].flatten.all? { |a| a && a.selected? }
      else
        if block || args.size > 0
          raise ArgumentError.new("wrong number of arguments #{args.size} for 0 or block given")
        end
        get(name)
      end
    end

    # Return an anonymous module
    #   # first create a requirement
    #   artifact_ns.cool_aid! 'cool:aid:jar:>=1.0'
    #
    #   # extend an object as a cool_aid delegator
    #   jars = Object.new.extend(artifact_ns.accessor(:cool_aid))
    #   jars.cool_aid = '2.0'
    #
    #   artifact_ns.cool_aid.version # -> '2.0'
    def accessor(*names)
      ns = self
      Module.new do
        names.each do |name|
          define_method("#{name}") { ns.send("#{name}") }
          define_method("#{name}?") { ns.send("#{name}?") }
          define_method("#{name}=") { |vers| ns.send("#{name}=", vers) }
        end
      end
    end

   private
    def get(name, include_parents = true, include_subs = true, include_self = true) #:nodoc:
      artifact = nil
      if include_subs && name.to_s[/_/] # try sub namespaces first
        sub, parts = self, name.to_s.split('_')
        sub_name = parts.shift.to_sym
        until sub != self || parts.empty?
          if registry[sub_name].kind_of?(ArtifactNamespace)
            sub = registry[sub_name]
            artifact = sub[parts.join('_')]
          else
            sub_name = [sub_name, parts.shift].join('_').to_sym
          end
        end
      end
      unless artifact
        if include_self
          artifact = registry.get(name, include_parents)
        elsif include_parents && registry.parent
          artifact = registry.parent.get(name, true)
        end
      end
      artifact = artifact.call if artifact && artifact.respond_to?(:call)
      artifact
    end

    def registry
      @registry ||= Registry.new.tap do |m|
        m.parent = parent.send(:registry) unless root?
      end
    end

  end # ArtifactNamespace

  # :call-seq:
  #   project.artifact_ns -> ArtifactNamespace
  #   Buildr.artifact_ns(name) -> ArtifactNamespace
  #   Buildr.artifact_ns -> ArtifactNamespace for the currently running Project
  #
  # Open an ArtifactNamespace.
  # If a block is provided, the namespace is yielded to it.
  #
  # See also ArtifactNamespace.instance
  def artifact_ns(name = nil, &block)
    name = self if name.nil? && self.kind_of?(Project)
    ArtifactNamespace.instance(name, &block)
  end

end
