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


require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helpers'))

describe Buildr.method(:struct) do
  before do
    @hash = { :foo=>'foo:jar', :bar=>'bar:jar' }
    @struct = struct(@hash)
  end

  it 'should be object with key-value pairs' do
    @struct.foo.should eql('foo:jar')
    @struct.bar.should eql('bar:jar')
  end

  it 'should fail when requesting non-existent key' do
    lambda { @struct.foobar }.should raise_error(NoMethodError)
  end

  it 'should return members when requested' do
    @struct.members.map(&:to_s).sort.should eql(@hash.keys.map(&:to_s).sort)
  end

  it 'should return valued when requested' do
    @struct.values.sort.should eql(@hash.values.sort)
  end
end


describe Buildr.method(:write) do
  it 'should create path' do
    write 'foo/test'
    File.directory?('foo').should be_true
    File.exist?('foo/test').should be_true
  end

  it 'should write content to file' do
    write 'test', 'content'
    File.read('test').should eql('content')
  end

  it 'should retrieve content from block, if block given' do
    write('test') { 'block' }
    File.read('test').should eql('block')
  end

  it 'should write empty file if no content provided' do
    write 'test'
    File.read('test').should eql('')
  end

  it 'should return content as a string' do
    write('test', 'content').should eql('content')
  end

  it 'should return empty string if no content provided' do
    write('test').should eql('')
  end
end


describe Buildr.method(:read) do
  before do
    write @file = 'test', @content = 'content'
  end

  it 'should return contents of named file' do
    read(@file).should eql(@content)
  end

  it 'should yield to block if block given' do
    read @file do |content|
      content.should eql(@content)
    end
  end

  it 'should return block response if block given' do
    read(@file) { 5 }.should be(5)
  end
end


describe Buildr.method(:download) do
  before do
    @content = 'we has download!'
    @http = double('http')
    @http.stub(:request).and_return(Net::HTTPNotModified.new(nil, nil, nil))
  end

  def tasks()
    [ download('http://localhost/download'), download('downloaded'=>'http://localhost/download') ]
  end

  it 'should be a file task' do
    tasks.each { |task| task.should be_kind_of(Rake::FileTask) }
  end

  it 'should accept a String and download from that URL' do
    define 'foo' do
      download('http://localhost/download').tap do |task|
        task.source.should_receive(:read).and_yield [@content]
        task.invoke
        task.should contain(@content)
      end
    end
  end

  it 'should accept a URI and download from that URL' do
    define 'foo' do
      download(URI.parse('http://localhost/download')).tap do |task|
        task.source.should_receive(:read).and_yield [@content]
        task.invoke
        task.should contain(@content)
      end
    end
  end

  it 'should accept a path and String and download from that URL' do
    define 'foo' do
      download('downloaded'=>'http://localhost/download').tap do |task|
        task.source.should_receive(:read).and_yield [@content]
        task.invoke
        task.should contain(@content)
      end
    end
  end

  it 'should accept an artifact and String and download from that URL' do
    define 'foo' do
      artifact('com.example:library:jar:2.0').tap do |artifact|
        download(artifact=>'http://localhost/download').source.should_receive(:read).and_yield [@content]
        artifact.invoke
        artifact.should contain(@content)
      end
    end
  end

  it 'should accept a path and URI and download from that URL' do
    define 'foo' do
      download('downloaded'=>URI.parse('http://localhost/download')).tap do |task|
        task.source.should_receive(:read).and_yield [@content]
        task.invoke
        task.should contain(@content)
      end
    end
  end

  it 'should create path for download' do
    define 'foo' do
      download('path/downloaded'=>URI.parse('http://localhost/download')).tap do |task|
        task.source.should_receive(:read).and_yield [@content]
        task.invoke
        task.should contain(@content)
      end
    end
  end

  it 'should fail if resource not found' do
    tasks.each do |task|
      task.source.should_receive(:read).and_raise URI::NotFoundError
      lambda { task.invoke }.should raise_error(URI::NotFoundError)
    end
    tasks.last.should_not exist
  end

  it 'should fail on any other error' do
    tasks.each do |task|
      task.source.should_receive(:read).and_raise RuntimeError
      lambda { task.invoke }.should raise_error(RuntimeError)
    end
    tasks.last.should_not exist
  end

  it 'should execute only if file does not already exist' do
    define 'foo' do
      download('downloaded'=>'http://localhost/download').tap do |task|
        task.source.should_not_receive(:read)
        write task.to_s, 'not really'
        task.invoke
      end
    end
  end

  it 'should execute without a proxy if none specified' do
    Net::HTTP.should_receive(:new).with('localhost', 80).twice.and_return(@http)
    tasks.each(&:invoke)
  end

  it 'should pass Buildr proxy options' do
    Buildr.options.proxy.http = 'http://proxy:8080'
    Net::HTTP.should_receive(:new).with('localhost', 80, 'proxy', 8080, nil, nil).twice.and_return(@http)
    tasks.each(&:invoke)
  end

  it 'should set HTTP proxy from HTTP_PROXY environment variable' do
    ENV['HTTP_PROXY'] = 'http://proxy:8080'
    Net::HTTP.should_receive(:new).with('localhost', 80, 'proxy', 8080, nil, nil).twice.and_return(@http)
    tasks.each(&:invoke)
  end
end


describe Buildr.method(:filter) do
  def source
    File.expand_path('src')
  end

  it 'should return a Filter for the source' do
    filter(source).should be_kind_of(Filter)
  end

  it 'should use the source directory' do
    filter(source).sources.should include(file(source))
  end

  it 'should use the source directories' do
    dirs = ['first', 'second']
    filter('first', 'second').sources.should include(*dirs.map { |dir| file(File.expand_path(dir)) })
  end

  it 'should accept a file task' do
    task = file(source)
    filter(task).sources.each { |source| source.should be(task) }
  end
end


describe Buildr::Filter do
  before do
    @filter = Filter.new
    1.upto(4) do |i|
      write "src/file#{i}", "file#{i} raw"
    end
    @early = Time.now - 1000
  end

  it 'should respond to :from and return self' do
    @filter.from('src').should be(@filter)
  end

  it 'should respond to :from and add source directory' do
    lambda { @filter.from('src') }.should change { @filter.sources }
  end

  it 'should respond to :from and add source directories' do
    dirs = ['first', 'second']
    @filter.from(*dirs)
    @filter.sources.should include(*dirs.map { |dir| file(File.expand_path(dir)) })
  end

  it 'should return source directories as file task' do
    @filter.from('src').sources.each { |source| source.should be_kind_of(Rake::FileTask) }
  end

  it 'should return source directories as expanded path' do
    @filter.from('src').sources.each { |source| source.to_s.should eql(File.expand_path('src')) }
  end

  it 'should respond to :into and return self' do
    @filter.into('target').should be(@filter)
  end

  it 'should respond to :into and set target directory' do
    lambda { @filter.into('src') }.should change { @filter.target }
    @filter.into('target').target.should be(file(File.expand_path('target')))
  end

  it 'should return target directory as file task' do
    @filter.into('target').target.should be_kind_of(Rake::FileTask)
  end

  it 'should return target directory as expanded path' do
    @filter.into('target').target.to_s.should eql(File.expand_path('target'))
  end

  it 'should respond to :using and return self' do
    @filter.using().should be(@filter)
  end

  it 'should respond to :using and set mapping from the argument' do
    mapping = { 'foo'=>'bar' }
    lambda { @filter.using mapping }.should change { @filter.mapping }.to(mapping)
  end

  it 'should respond to :using and set mapping from the block' do
    @filter.using { 5 }.mapping.call.should be(5)
  end

  it 'should respond to :include and return self' do
    @filter.include('file').should be(@filter)
  end

  it 'should respond to :include and use these inclusion patterns' do
    @filter.from('src').into('target').include('file2', 'file3').run
    Dir['target/*'].sort.should eql(['target/file2', 'target/file3'])
  end

  it 'should respond to :include with regular expressions and use these inclusion patterns' do
    @filter.from('src').into('target').include(/file[2|3]/).run
    Dir['target/*'].sort.should eql(['target/file2', 'target/file3'])
  end

  it 'should respond to :include with a Proc and use these inclusion patterns' do
    @filter.from('src').into('target').include(lambda {|file| file[-1, 1].to_i%2 == 0}).run
    Dir['target/*'].sort.should eql(['target/file2', 'target/file4'])
  end

  it 'should respond to :include with a FileTask and use these inclusion patterns' do
    @filter.from('src').into('target').include(file('target/file2'), file('target/file4')).run
    Dir['target/*'].sort.should eql(['target/file2', 'target/file4'])
  end

  it 'should respond to :exclude and return self' do
    @filter.exclude('file').should be(@filter)
  end

  it 'should respond to :exclude and use these exclusion patterns' do
    @filter.from('src').into('target').exclude('file2', 'file3').run
    Dir['target/*'].sort.should eql(['target/file1', 'target/file4'])
  end

  it 'should respond to :exclude with regular expressions and use these exclusion patterns' do
    @filter.from('src').into('target').exclude(/file[2|3]/).run
    Dir['target/*'].sort.should eql(['target/file1', 'target/file4'])
  end

  it 'should respond to :exclude with a Proc and use these exclusion patterns' do
    @filter.from('src').into('target').exclude(lambda {|file| file[-1, 1].to_i%2 == 0}).run
    Dir['target/*'].sort.should eql(['target/file1', 'target/file3'])
  end

  it 'should respond to :exclude with a FileTask and use these exclusion patterns' do
    @filter.from('src').into('target').exclude(file('target/file1'), file('target/file3')).run
    Dir['target/*'].sort.should eql(['target/file2', 'target/file4'])
  end

  it 'should respond to :exclude with a FileTask, use these exclusion patterns and depend on those tasks' do
    file1 = false
    file2 = false
    @filter.from('src').into('target').exclude(file('target/file1').enhance { file1 = true }, file('target/file3').enhance {file2 = true }).run
    Dir['target/*'].sort.should eql(['target/file2', 'target/file4'])
    @filter.target.invoke
    file1.should be_true
    file2.should be_true
  end

  it 'should copy files over' do
    @filter.from('src').into('target').run
    Dir['target/*'].sort.each do |file|
      read(file).should eql("#{File.basename(file)} raw")
    end
  end

  it 'should copy dot files over' do
    write 'src/.config', '# configuration'
    @filter.from('src').into('target').run
    read('target/.config').should eql('# configuration')
  end

  it 'should copy empty directories as well' do
    mkpath 'src/empty'
    @filter.from('src').into('target').run
    File.directory?('target/empty').should be_true
  end

  it 'should copy files from multiple source directories' do
    4.upto(6) { |i| write "src2/file#{i}", "file#{i} raw" }
    @filter.from('src', 'src2').into('target').run
    Dir['target/*'].each do |file|
      read(file).should eql("#{File.basename(file)} raw")
    end
    Dir['target/*'].should include(*(1..6).map { |i| "target/file#{i}" })
  end

  it 'should copy files recursively' do
    mkpath 'src/path1' ; write 'src/path1/left'
    mkpath 'src/path2' ; write 'src/path2/right'
    @filter.from('src').into('target').run
    Dir['target/**/*'].should include(*(1..4).map { |i| "target/file#{i}" })
    Dir['target/**/*'].should include('target/path1/left', 'target/path2/right')
  end

  it 'should apply hash mapping using Maven style' do
    1.upto(4) { |i| write "src/file#{i}", "file#{i} with ${key1} and ${key2}" }
    @filter.from('src').into('target').using('key1'=>'value1', 'key2'=>'value2').run
    Dir['target/*'].each do |file|
      read(file).should eql("#{File.basename(file)} with value1 and value2")
    end
  end
  
  it 'should not apply filters to binary files' do
    ["jpg", "jpeg", "gif", "png"].each { |ext| write "images/file.#{ext}", 'something' }
    filter = @filter.from('images').into('target').using('key1'=>'value1', 'key2'=>'value2')
    filter.instance_variable_get("@mapper").should_not_receive(:maven_transform)
    filter.run
  end

  it 'should apply hash mapping using Ant style' do
    1.upto(4) { |i| write "src/file#{i}", "file#{i} with @key1@ and @key2@" }
    @filter.from('src').into('target').using(:ant, 'key1'=>'value1', 'key2'=>'value2').run
    Dir['target/*'].each do |file|
      read(file).should eql("#{File.basename(file)} with value1 and value2")
    end
  end

  it 'should apply hash mapping using Ruby style' do
    1.upto(4) { |i| write "src/file#{i}", "file#{i} with \#{key1} and \#{key2}" }
    @filter.from('src').into('target').using(:ruby, 'key1'=>'value1', 'key2'=>'value2').run
    Dir['target/*'].each do |file|
      read(file).should eql("#{File.basename(file)} with value1 and value2")
    end
  end

  it 'should use erb when given a binding' do
    1.upto(4) { |i| write "src/file#{i}", "file#{i} with <%= key1 %> and <%= key2 * 2 %>" }
    key1 = 'value1'
    key2 = 12
    @filter.from('src').into('target').using(binding).run
    Dir['target/*'].each do |file|
      read(file).should eql("#{File.basename(file)} with value1 and 24")
    end
  end

  it 'should apply hash mapping using erb' do
    1.upto(4) { |i| write "src/file#{i}", "file#{i} with <%= key1 %> and <%= key2 * 2 %>" }
    @filter.from('src').into('target').using(:erb, 'key1'=>'value1', 'key2'=> 12).run
    Dir['target/*'].each do |file|
      read(file).should eql("#{File.basename(file)} with value1 and 24")
    end
  end

  it 'should use an object binding when using erb' do
    1.upto(4) { |i| write "src/file#{i}", "file#{i} with <%= key1 %> and <%= key2 * 2 %>" }
    obj = Struct.new(:key1, :key2).new('value1', 12)
    @filter.from('src').into('target').using(:erb, obj).run
    Dir['target/*'].each do |file|
      read(file).should eql("#{File.basename(file)} with value1 and 24")
    end
  end

  it 'should use a given block context when using erb' do
    1.upto(4) { |i| write "src/file#{i}", "file#{i} with <%= key1 %> and <%= key2 * 2 %>" }
    key1 = 'value1'
    key2 = 12
    @filter.from('src').into('target').using(:erb){}.run
    Dir['target/*'].each do |file|
      read(file).should eql("#{File.basename(file)} with value1 and 24")
    end
  end

  it 'should using Maven mapper by default' do
    @filter.using('key1'=>'value1', 'key2'=>'value2').mapper.should eql(:maven)
  end

  it 'should apply hash mapping with boolean values' do
    write "src/file", "${key1} and ${key2}"
    @filter.from('src').into('target').using(:key1=>true, :key2=>false).run
    read("target/file").should eql("true and false")
  end

  it 'should apply hash mapping using regular expression' do
    1.upto(4) { |i| write "src/file#{i}", "file#{i} with #key1# and #key2#" }
    @filter.from('src').into('target').using(/#(.*?)#/, 'key1'=>'value1', 'key2'=>'value2').run
    Dir['target/*'].each do |file|
      read(file).should eql("#{File.basename(file)} with value1 and value2")
    end
  end

  it 'should apply proc mapping' do
    @filter.from('src').into('target').using { |file, content| 'proc mapped' }.run
    Dir['target/*'].each do |file|
      read(file).should eql('proc mapped')
    end
  end

  it 'should apply proc mapping with relative file name' do
    @filter.from('src').into('target').using { |file, content| file.should =~ /^file\d$/ }.run
  end

  it 'should apply proc mapping with file content' do
    @filter.from('src').into('target').using { |file, content| content.should =~ /^file\d raw/ }.run
  end

  it 'should make target directory' do
    lambda { @filter.from('src').into('target').run }.should change { File.exist?('target') }.to(true)
  end

  it 'should touch target directory' do
    mkpath 'target' ; File.utime @early, @early, 'target'
    @filter.from('src').into('target').run
    File.stat('target').mtime.should be_within(10).of(Time.now)
  end

  it 'should not touch target directory unless running' do
    mkpath 'target' ; File.utime @early, @early, 'target'
    @filter.from('src').into('target').exclude('*').run
    File.mtime('target').should be_within(10).of(@early)
  end

  it 'should run only on new files' do
    # Make source files older so they're not copied twice.
    Dir['src/**/*'].each { |file| File.utime(@early, @early, file) }
    @filter.from('src').into('target').run
    @filter.from('src').into('target').using { |file, content| file.should eql('file2') }.run
  end

  it 'should return true when run copies any files' do
    @filter.from('src').into('target').run.should be(true)
  end

  it 'should return false when run does not copy any files' do
    # Make source files older so they're not copied twice.
    Dir['src/**/*'].each { |file| File.utime(@early, @early, file) }
    @filter.from('src').into('target').run
    @filter.from('src').into('target').run.should be(false)
  end

  it 'should fail if source directory doesn\'t exist' do
    lambda { Filter.new.from('srced').into('target').run }.should raise_error(RuntimeError, /doesn't exist/)
  end

  it 'should fail is target directory not set' do
    lambda { Filter.new.from('src').run }.should raise_error(RuntimeError, /No target directory/)
  end

  it 'should copy read-only files as writeable' do
    Dir['src/*'].each { |file| File.chmod(0444, file) }
    @filter.from('src').into('target').run
    Dir['target/*'].sort.each do |file|
      File.readable?(file).should be_true
      File.writable?(file).should be_true
      (File.stat(file).mode & 0o200).should == 0o200
    end
  end

  it 'should preserve mode bits except readable' do
    mode = 0o600
    Dir['src/*'].each { |file| File.chmod(mode, file) }
    @filter.from('src').into('target').run
    Dir['target/*'].sort.each do |file|
      (File.stat(file).mode & mode).should == mode
    end
  end
end

describe Filter::Mapper do

  module MooMapper
    def moo_config(*args, &block)
      raise ArgumentError, "Expected moo block" unless block_given?
      { :moos => args, :callback => block }
    end

    def moo_transform(content, path = nil)
      content.gsub(/moo+/i) do |str|
        moos = yield :moos # same than config[:moos]
        moo = moos[str.size - 3] || str
        config[:callback].call(moo)
      end
    end
  end

  it 'should allow plugable mapping types' do
    mapper = Filter::Mapper.new.extend(MooMapper)
    mapper.using(:moo, 'ooone', 'twoo') do |str|
      i = nil; str.capitalize.gsub(/\w/) { |s| s.send( (i = !i) ? 'upcase' : 'downcase' ) }
    end
    mapper.transform('Moo cow, mooo cows singing mooooo').should == 'OoOnE cow, TwOo cows singing MoOoOo'
  end

end

describe Buildr.method(:options) do
  it 'should return an Options object' do
    options.should be_kind_of(Options)
  end

  it 'should return an Options object each time' do
    options.should be(options)
  end

  it 'should return the same Options object when called on Object, Buildr or Project' do
    options.should be(Buildr.options)
    define('foo') { options.should be(Buildr.options) }
  end
end

describe Buildr::Options, 'proxy.exclude' do
  before do
    options.proxy.http = 'http://myproxy:8080'
    options.proxy.exclude.clear
    @domain = 'domain'
    @host = "host.#{@domain}"
    @uri = URI("http://#{@host}")
    @no_proxy_args = [@host, 80]
    @proxy_args = @no_proxy_args + ['myproxy', 8080, nil, nil]
    @http = double('http')
    @http.stub(:request).and_return(Net::HTTPNotModified.new(nil, nil, nil))
  end

  it 'should be an array' do
    options.proxy.exclude.should be_empty
    options.proxy.exclude = @domain
    options.proxy.exclude.should include(@domain)
  end

  it 'should support adding to array' do
    options.proxy.exclude << @domain
    options.proxy.exclude.should include(@domain)
  end

  it 'should support resetting array' do
    options.proxy.exclude = @domain
    options.proxy.exclude = nil
    options.proxy.exclude.should be_empty
  end

  it 'should use proxy when not excluded' do
    Net::HTTP.should_receive(:new).with(*@proxy_args).and_return(@http)
    @uri.read :proxy=>options.proxy
  end

  it 'should use proxy unless excluded' do
    options.proxy.exclude = "not.#{@domain}"
    Net::HTTP.should_receive(:new).with(*@proxy_args).and_return(@http)
    @uri.read :proxy=>options.proxy
  end

  it 'should not use proxy if excluded' do
    options.proxy.exclude = @host
    Net::HTTP.should_receive(:new).with(*@no_proxy_args).and_return(@http)
    @uri.read :proxy=>options.proxy
  end

  it 'should support multiple host names' do
    options.proxy.exclude = ['optimus', 'prime']
    Net::HTTP.should_receive(:new).with('optimus', 80).and_return(@http)
    URI('http://optimus').read :proxy=>options.proxy
    Net::HTTP.should_receive(:new).with('prime', 80).and_return(@http)
    URI('http://prime').read :proxy=>options.proxy
    Net::HTTP.should_receive(:new).with('bumblebee', *@proxy_args[1..-1]).and_return(@http)
    URI('http://bumblebee').read :proxy=>options.proxy
  end

  it 'should support glob pattern on host name' do
    options.proxy.exclude = "*.#{@domain}"
    Net::HTTP.should_receive(:new).with(*@no_proxy_args).and_return(@http)
    @uri.read :proxy=>options.proxy
  end
end


describe Hash, '::from_java_properties' do
  it 'should return hash' do
    hash = Hash.from_java_properties(<<-PROPS)
name1=value1
name2=value2
    PROPS
    hash.should == {'name1'=>'value1', 'name2'=>'value2'}
  end

  it 'should ignore comments and empty lines' do
    hash = Hash.from_java_properties(<<-PROPS)

name1=value1

name2=value2

PROPS
    hash.should == {'name1'=>'value1', 'name2'=>'value2'}
  end

  it 'should allow multiple lines' do
    hash = Hash.from_java_properties(<<-PROPS)
name1=start\
 end

name2=first\
 second\
 third

PROPS
    hash.should == {'name1'=>'start end', 'name2'=>'first second third'}
  end

  it 'should handle \t, \r, \n and \f' do
    hash = Hash.from_java_properties(<<-PROPS)

name1=with\tand\r

name2=with\\nand\f

name3=double\\\\hash
PROPS
    hash.should == {'name1'=>"with\tand", 'name2'=>"with\nand\f", 'name3'=>'double\hash'}
  end

  it 'should ignore whitespace' do
    hash = Hash.from_java_properties('name1 = value1')
    hash.should == {'name1'=>'value1'}
  end
end


describe Hash, '#to_java_properties' do
  it 'should return name/value pairs' do
    props = {'name1'=>'value1', 'name2'=>'value2'}.to_java_properties
    props.split("\n").size.should be(2)
    props.split("\n").should include('name1=value1')
    props.split("\n").should include('name2=value2')
  end

  it 'should handle \t, \r, \n and \f' do
    props = {'name1'=>"with\tand\r", 'name2'=>"with\nand\f", 'name3'=>'double\hash'}.to_java_properties
    props.split("\n").should include("name1=with\\tand\\r")
    props.split("\n").should include("name2=with\\nand\\f")
    props.split("\n").should include("name3=double\\\\hash")
  end
end
