# 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 'zip'

if RUBY_VERSION >= '1.9.0' # Required to properly load RubyZip under Ruby 1.9
  $LOADED_FEATURES.unshift 'ftools'
  require 'fileutils'

  def File.move(source, dest)
    FileUtils.move source, dest
  end

  def File.rm_rf(path)
    FileUtils.rm_rf path
  end
end

module Zip #:nodoc:

  class CentralDirectory #:nodoc:
    # Patch to add entries in alphabetical order.
    def write_to_stream(io)
      offset = io.tell
      @entry_set.sort { |a,b| a.name <=> b.name }.each { |entry| entry.write_c_dir_entry(io) }
      eocd_offset = io.tell
      cdir_size = eocd_offset - offset
      write_e_o_c_d(io, offset, cdir_size)
    end
  end

  class File

    # :call-seq:
    #   exist() => boolean
    #
    # Returns true if this entry exists.
    def exist?(entry_name)
      !!find_entry(entry_name)
    end
  end


  class Entry

    # :call-seq:
    #   exist() => boolean
    #
    # Returns true if this entry exists.
    def exist?()
      File.open(zipfile) { |zip| zip.exist?(@name) }
    end

    # :call-seq:
    #   empty?() => boolean
    #
    # Returns true if this entry is empty.
    def empty?()
      File.open(zipfile) { |zip| zip.read(@name) }.empty?
    end

    # :call-seq:
    #   contain(patterns*) => boolean
    #
    # Returns true if this ZIP file entry matches against all the arguments. An argument may be
    # a string or regular expression.
    def contain?(*patterns)
      content = File.open(zipfile) { |zip| zip.read(@name) }
      patterns.map { |pattern| Regexp === pattern ? pattern : Regexp.new(Regexp.escape(pattern.to_s)) }.
        all? { |pattern| content =~ pattern }
    end

    # Override of write_c_dir_entry to fix comments being set to a fixnum instead of string
    def write_c_dir_entry(io) #:nodoc:all
      case @fstype
        when FSTYPE_UNIX
          ft = nil
          case @ftype
            when :file
              ft = 010
              @unix_perms ||= 0644
            when :directory
              ft = 004
              @unix_perms ||= 0755
            when :symlink
              ft = 012
              @unix_perms ||= 0755
            else
              raise ZipInternalError, "unknown file type #{self.inspect}"
          end

          @external_file_attributes = (ft << 12 | (@unix_perms & 07777)) << 16
      end

      io <<
        [0x02014b50,
         @version,                  # version of encoding software
         @fstype,                   # filesystem type
         10,                        # @versionNeededToExtract
         0,                         # @gp_flags
         @compression_method,
         @time.to_binary_dos_time,  # @lastModTime
         @time.to_binary_dos_date,  # @lastModDate
         @crc,
         @compressed_size,
         @size,
         @name ? @name.length : 0,
         @extra ? @extra.c_dir_size : 0,
         @comment ? comment.to_s.length : 0,
         0,                         # disk number start
         @internal_file_attributes,   # file type (binary=0, text=1)
         @external_file_attributes,   # native filesystem attributes
         @local_header_offset,
         @name,
         @extra,
         @comment
      ].pack('VCCvvvvvVVVvvvvvVV')

      io << @name
      io << (@extra ? @extra.to_c_dir_bin : "")
      io << @comment
    end

    # Override write_c_dir_entry to fix comments being set to a fixnum instead of string
    def write_c_dir_entry(io) #:nodoc:all
      @comment = "" if @comment.nil? || @comment == -1  # Hack fix @comment being nil or fixnum -1

      case @fstype
        when FSTYPE_UNIX
          ft = nil
          case @ftype
            when :file
              ft = 010
              @unix_perms ||= 0644
            when :directory
              ft = 004
              @unix_perms ||= 0755
            when :symlink
              ft = 012
              @unix_perms ||= 0755
            else
              raise ZipInternalError, "unknown file type #{self.inspect}"
          end

          @external_file_attributes = (ft << 12 | (@unix_perms & 07777)) << 16
      end

      io <<
        [0x02014b50,
         @version,                  # version of encoding software
         @fstype,                   # filesystem type
         10,                        # @versionNeededToExtract
         0,                         # @gp_flags
         @compression_method,
         @time.to_binary_dos_time,  # @lastModTime
         @time.to_binary_dos_date,  # @lastModDate
         @crc,
         @compressed_size,
         @size,
         @name ? @name.length : 0,
         @extra ? @extra.c_dir_size : 0,
         @comment ? @comment.length : 0,
         0,                         # disk number start
         @internal_file_attributes,   # file type (binary=0, text=1)
         @external_file_attributes,   # native filesystem attributes
         @local_header_offset,
         @name,
         @extra,
         @comment].pack('VCCvvvvvVVVvvvvvVV')

      io << @name
      io << (@extra ? @extra.to_c_dir_bin : "")
      io << @comment

    end
  end
end
