# Frozen-string-literal: true
# Copyright: 2015-2016 Jordon Bedwell - MIT License
# Encoding: utf-8

require "pathutil/helpers"
require "forwardable/extended"
require "find"

class Pathutil
  attr_writer :encoding
  extend Forwardable::Extended
  extend Helpers

  # --
  # @note A lot of this class can be compatible with Pathname.
  # Initialize a new instance.
  # @return Pathutil
  # --
  def initialize(path)
    return @path = path if path.is_a?(String)
    return @path = path.to_path if path.respond_to?(:to_path)
    return @path = path.to_s
  end

  # --
  # Make a path relative.
  # --

  def relative
    return self if relative?
    self.class.new(strip_windows_drive.gsub(
      %r!\A(\\+|/+)!, ""
    ))
  end

  # --
  # Make a path absolute
  # --

  def absolute
    return self if absolute?
    self.class.new("/").join(
      @path
    )
  end

  # --
  # @see Pathname#cleanpath.
  # @note This is a wholesale rip and cleanup of Pathname#cleanpath
  # @return Pathutil
  # --
  def cleanpath(symlink = false)
    symlink ? conservative_cleanpath : aggressive_cleanpath
  end

  # --
  # @yield Pathutil
  # @note It will return all results that it finds across all ascending paths.
  # @example Pathutil.new("~/").expand_path.search_backwards(".bashrc") => [#<Pathutil:/home/user/.bashrc>]
  # Search backwards for a file (like Rakefile, _config.yml, opts.yml).
  # @return Enum
  # --
  def search_backwards(file, backwards: Float::INFINITY)
    ary = []

    ascend.with_index(1).each do |path, index|
      if index > backwards
        break

      else
        Dir.chdir path do
          if block_given?
            file = self.class.new(file)
            if yield(file)
              ary.push(
                file
              )
            end

          elsif File.exist?(file)
            ary.push(self.class.new(
              path.join(file)
            ))
          end
        end
      end
    end

    ary
  end

  # --
  # Read the file as a YAML file turning it into an object.
  # @see self.class.load_yaml as this a direct alias of that method.
  # @return Hash
  # --
  def read_yaml(throw_missing: false, **kwd)
    self.class.load_yaml(
      read, **kwd
    )

  rescue Errno::ENOENT
    throw_missing ? raise : (
      return {}
    )
  end

  # --
  # Read the file as a JSON file turning it into an object.
  # @see self.class.read_json as this is a direct alias of that method.
  # @return Hash
  # --
  def read_json(throw_missing: false)
    JSON.parse(
      read
    )

  rescue Errno::ENOENT
    throw_missing ? raise : (
      return {}
    )
  end

  # --
  # @note The blank part is intentionally left there so that you can rejoin.
  # Splits the path into all parts so that you can do step by step comparisons
  # @example Pathutil.new("/my/path").split_path # => ["", "my", "path"]
  # @return Array<String>
  # --
  def split_path
    @path.split(
      %r!\\+|/+!
    )
  end

  # --
  # @see `String#==` for more details.
  # A stricter version of `==` that also makes sure the object matches.
  # @return true|false
  # --
  def ===(other)
    other.is_a?(self.class) && @path == other
  end

  # --
  # @example Pathutil.new("/hello") >= Pathutil.new("/") # => true
  # @example Pathutil.new("/hello") >= Pathutil.new("/hello") # => true
  # Checks to see if a path falls within a path and deeper or is the other.
  # @return true|false
  # --
  def >=(other)
    mine, other = expanded_paths(other)
    return true if other == mine
    mine.in_path?(other)
  end

  # --
  # @example Pathutil.new("/hello/world") > Pathutil.new("/hello") # => true
  # Strictly checks to see if a path is deeper but within the path of the other.
  # @return true|false
  # --
  def >(other)
    mine, other = expanded_paths(other)
    return false if other == mine
    mine.in_path?(other)
  end

  # --
  # @example Pathutil.new("/") < Pathutil.new("/hello") # => true
  # Strictly check to see if a path is behind other path but within it.
  # @return true|false
  # --
  def <(other)
    mine, other = expanded_paths(other)
    return false if other == mine
    other.in_path?(mine)
  end

  # --
  # Check to see if a path is behind the other path but within it.
  # @example Pathutil.new("/hello") < Pathutil.new("/hello") # => true
  # @example Pathutil.new("/") < Pathutil.new("/hello") # => true
  # @return true|false
  # --
  def <=(other)
    mine, other = expanded_paths(other)
    return true if other == mine
    other.in_path?(mine)
  end

  # --
  # @note "./" is considered relative.
  # Check to see if the path is absolute, as in: starts with "/"
  # @return true|false
  # --
  def absolute?
    return !!(
      @path =~ %r!\A(?:[A-Za-z]:)?(?:\\+|/+)!
    )
  end

  # --
  # @yield Pathutil
  # Break apart the path and yield each with the previous parts.
  # @example Pathutil.new("/hello/world").ascend.to_a # => ["/", "/hello", "/hello/world"]
  # @example Pathutil.new("/hello/world").ascend { |path| $stdout.puts path }
  # @return Enum
  # --
  def ascend
    unless block_given?
      return to_enum(
        __method__
      )
    end

    yield(
      path = self
    )

    while (new_path = path.dirname)
      if path == new_path || new_path == "."
        break
      else
        path = new_path
        yield  new_path
      end
    end

    nil
  end

  # --
  # @yield Pathutil
  # Break apart the path in reverse order and descend into the path.
  # @example Pathutil.new("/hello/world").descend.to_a # => ["/hello/world", "/hello", "/"]
  # @example Pathutil.new("/hello/world").descend { |path| $stdout.puts path }
  # @return Enum
  # --
  def descend
    unless block_given?
      return to_enum(
        __method__
      )
    end

    ascend.to_a.reverse_each do |val|
      yield val
    end

    nil
  end

  # --
  # @yield Pathutil
  # @example Pathutil.new("/hello/world").each_line { |line| $stdout.puts line }
  # Wraps `readlines` and allows you to yield on the result.
  # @return Enum
  # --
  def each_line
    return to_enum(__method__) unless block_given?
    readlines.each do |line|
      yield line
    end

    nil
  end

  # --
  # @example Pathutil.new("/hello").fnmatch?("/hello") # => true
  # Unlike traditional `fnmatch`, with this one `Regexp` is allowed.
  # @example Pathutil.new("/hello").fnmatch?(/h/) # => true
  # @see `File#fnmatch` for more information.
  # @return true|false
  # --
  def fnmatch?(matcher)
    matcher.is_a?(Regexp) ? !!(self =~ matcher) : \
      File.fnmatch(matcher, self)
  end

  # --
  # Allows you to quickly determine if the file is the root folder.
  # @return true|false
  # --
  def root?
    !!(self =~ %r!\A(?:[A-Za-z]:)?(?:\\+|/+)\z!)
  end

  # --
  # Allows you to check if the current path is in the path you want.
  # @return true|false
  # --
  def in_path?(path)
    path = self.class.new(path).expand_path.split_path
    mine = (symlink?? expand_path.realpath : expand_path).split_path
    path.each_with_index { |part, index| return false if mine[index] != part }
    true
  end

  # --

  def inspect
    "#<#{self.class}:#{@path}>"
  end

  # --
  # @return Array<Pathutil>
  # Grab all of the children from the current directory, including hidden.
  # @yield Pathutil
  # --
  def children
    ary = []

    Dir.foreach(@path) do |path|
      if path == "." || path == ".."
        next
      else
        path = self.class.new(File.join(@path, path))
        yield path if block_given?
        ary.push(
          path
        )
      end
    end

    ary
  end

  # --
  # @yield Pathutil
  # Allows you to glob however you wish to glob in the current `Pathutil`
  # @see `File::Constants` for a list of flags.
  # @return Enum
  # --
  def glob(pattern, flags = 0)
    unless block_given?
      return to_enum(
        __method__, pattern, flags
      )
    end

    chdir do
      Dir.glob(pattern, flags).each do |file|
        yield self.class.new(
          File.join(@path, file)
        )
      end
    end

    nil
  end

  # --
  # @yield &block
  # Move to the current directory temporarily (or for good) and do work son.
  # @note you do not need to ship a block at all.
  # @return nil
  # --
  def chdir
    if !block_given?
      Dir.chdir(
        @path
      )

    else
      Dir.chdir @path do
        yield
      end
    end
  end

  # --
  # @yield Pathutil
  # Find all files without care and yield the given block.
  # @return Enum
  # --
  def find
    return to_enum(__method__) unless block_given?
    Find.find @path do |val|
      yield self.class.new(val)
    end
  end

  # --
  # @yield Pathutil
  # Splits the path returning each part (filename) back to you.
  # @return Enum
  # --
  def each_filename
    return to_enum(__method__) unless block_given?
    @path.split(File::SEPARATOR).delete_if(&:empty?).each do |file|
      yield file
    end
  end

  # --
  # Get the parent of the current path.
  # @note This will simply return self if "/".
  # @return Pathutil
  # --
  def parent
    return self if @path == "/"
    self.class.new(absolute?? File.dirname(@path) : File.join(
      @path, ".."
    ))
  end

  # --
  # @yield Pathutil
  # Split the file into its dirname and basename, so you can do stuff.
  # @return nil
  # --
  def split
    File.split(@path).collect! do |path|
      self.class.new(path)
    end
  end

  # --
  # @note Your extension should start with "."
  # Replace a files extension with your given extension.
  # @return Pathutil
  # --
  def sub_ext(ext)
    self.class.new(@path.chomp(File.extname(@path)) + ext)
  end

  # --
  # A less complex version of `relative_path_from` that simply uses a
  # `Regexp` and returns the full path if it cannot be determined.
  # @return Pathutil
  # --
  def relative_path_from(from)
    from = self.class.new(from).expand_path.gsub(%r!/$!, "")
    self.class.new(expand_path.gsub(%r!^#{
      from.regexp_escape
    }/!, ""))
  end

  # --
  # Expands the path and left joins the root to the path.
  # @return Pathutil
  # --
  def enforce_root(root)
    return self if !relative? && in_path?(root)
    self.class.new(root).join(
      self
    )
  end

  # --
  # Copy a directory, allowing symlinks if the link falls inside of the root.
  # This is indented for people who wish some safety to their copies.
  # @note Ignore is ignored on safe_copy file because it's explicit.
  # @return nil
  # --
  def safe_copy(to, root: nil, ignore: [])
    raise ArgumentError, "must give a root" unless root
    root = self.class.new(root)
    to   = self.class.new(to)

    if directory?
      safe_copy_directory(to, {
        :root => root, :ignore => ignore
      })

    else
      safe_copy_file(to, {
        :root => root
      })
    end
  end

  # --
  # @see `self.class.normalize` as this is an alias.
  # --
  def normalize
    return @normalize ||= begin
      self.class.normalize
    end
  end

  # --
  # @see `self.class.encoding` as this is an alias.
  # --
  def encoding
    return @encoding ||= begin
      self.class.encoding
    end
  end

  # --
  # @note You can set the default encodings via the class.
  # Read took two steroid shots: it can normalize your string, and encode.
  # @return String
  # --
  def read(*args, **kwd)
    kwd[:encoding] ||= encoding

    if normalize[:read]
      File.read(self, *args, kwd).encode({
        :universal_newline => true
      })

    else
      File.read(
        self, *args, kwd
      )
    end
  end

  # --
  # @note You can set the default encodings via the class.
  # Binread took two steroid shots: it can normalize your string, and encode.
  # @return String
  # --
  def binread(*args, **kwd)
    kwd[:encoding] ||= encoding

    if normalize[:read]
      File.binread(self, *args, kwd).encode({
        :universal_newline => true
      })

    else
      File.read(
        self, *args, kwd
      )
    end
  end

  # --
  # @note You can set the default encodings via the class.
  # Readlines took two steroid shots: it can normalize your string, and encode.
  # @return Array<String>
  # --
  def readlines(*args, **kwd)
    kwd[:encoding] ||= encoding

    if normalize[:read]
      File.readlines(self, *args, kwd).encode({
        :universal_newline => true
      })

    else
      File.readlines(
        self, *args, kwd
      )
    end
  end

  # --
  # @note You can set the default encodings via the class.
  # Write took two steroid shots: it can normalize your string, and encode.
  # @return Fixnum<Bytes>
  # --
  def write(data, *args, **kwd)
    kwd[:encoding] ||= encoding

    if normalize[:write]
      File.write(self, data.encode(
        :crlf_newline => true
      ), *args, kwd)

    else
      File.write(
        self, data, *args, kwd
      )
    end
  end

  # --
  # @note You can set the default encodings via the class.
  # Binwrite took two steroid shots: it can normalize your string, and encode.
  # @return Fixnum<Bytes>
  # --
  def binwrite(data, *args, **kwd)
    kwd[:encoding] ||= encoding

    if normalize[:write]
      File.binwrite(self, data.encode(
        :crlf_newline => true
      ), *args, kwd)

    else
      File.binwrite(
        self, data, *args, kwd
      )
    end
  end

  # --

  def to_regexp(guard: true)
    Regexp.new((guard ? "\\A" : "") + Regexp.escape(
      self
    ))
  end

  # --
  # Strips the windows drive from the path.
  # --

  def strip_windows_drive(path = @path)
    self.class.new(path.gsub(
      %r!\A[A-Za-z]:(?:\\+|/+)!, ""
    ))
  end

  # --
  # rubocop:disable Metrics/AbcSize
  # rubocop:disable Metrics/CyclomaticComplexity
  # rubocop:disable Metrics/PerceivedComplexity
  # --

  def aggressive_cleanpath
    return self.class.new("/") if root?

    _out = split_path.each_with_object([]) do |part, out|
      next if part == "." || (part == ".." && out.last == "")
      if part == ".." && out.last && out.last != ".."
        out.pop

      else
        out.push(
          part
        )
      end
    end

    # --

    return self.class.new("/") if _out == [""].freeze
    return self.class.new(".") if _out.empty? && (end_with?(".") || relative?)
    self.class.new(_out.join("/"))
  end

  # --

  def conservative_cleanpath
    _out = split_path.each_with_object([]) do |part, out|
      next if part == "." || (part == ".." && out.last == "")
      out.push(
        part
      )
    end

    # --

    if !_out.empty? && basename == "." && _out.last != "" && _out.last != ".."
      _out << "."
    end

    # --

    return self.class.new("/") if _out == [""].freeze
    return self.class.new(".") if _out.empty? && (end_with?(".") || relative?)
    return self.class.new(_out.join("/")).join("") if @path =~ %r!/\z! \
      && _out.last != "." && _out.last != ".."
    self.class.new(_out.join("/"))
  end

  # --
  # rubocop:enable Metrics/AbcSize
  # rubocop:enable Metrics/CyclomaticComplexity
  # rubocop:enable Metrics/PerceivedComplexity
  # Expand the paths and return.
  # --
  private
  def expanded_paths(path)
    return expand_path, self.class.new(path).expand_path
  end

  # --
  # Safely copy a file.
  # --
  private
  def safe_copy_file(to, root: nil)
    raise Errno::EPERM, "#{self} not in #{root}" unless in_path?(root)
    FileUtils.cp(self, to, {
      :preserve => true
    })
  end

  # --
  # Safely copy a directory and it's sub-files.
  # --
  private
  def safe_copy_directory(to, root: nil, ignore: [])
    ignore = [ignore].flatten.uniq

    if !in_path?(root)
      raise Errno::EPERM, "#{self} not in #{
        root
      }"

    else
      to.mkdir_p unless to.exist?
      children do |file|
        unless ignore.any? { |path| file.in_path?(path) }
          if !file.in_path?(root)
            raise Errno::EPERM, "#{file} not in #{
              root
            }"

          elsif file.file?
            FileUtils.cp(file, to, {
              :preserve => true
            })

          else
            path = file.realpath
            path.safe_copy(to.join(file.basename), {
              :root => root, :ignore => ignore
            })
          end
        end
      end
    end
  end

  class << self
    attr_writer :encoding

    # --
    # @note We do nothing special here.
    # Get the current directory that Ruby knows about.
    # @return Pathutil
    # --
    def pwd
      new(
        Dir.pwd
      )
    end

    alias gcwd pwd
    alias cwd  pwd

    # --
    # @note you are encouraged to override this if you need to.
    # Aliases the default system encoding to us so that we can do most read
    # and write operations with that encoding, instead of being crazy.
    # --
    def encoding
      return @encoding ||= begin
        Encoding.default_external
      end
    end

    # --
    # Normalize CRLF -> LF   on Windows reads, to ease  your troubles.
    # Normalize LF   -> CLRF on Windows write, to ease  your troubles.
    # --
    def normalize
      return @normalize ||= {
        :read  => Gem.win_platform?,
        :write => Gem.win_platform?
      }
    end

    # --
    # Make a temporary directory.
    # @note if you adruptly exit it will not remove the dir.
    # @note this directory is removed on exit.
    # @return Pathutil
    # --
    def tmpdir(*args)
      rtn = new(make_tmpname(*args)).tap(&:mkdir)
      ObjectSpace.define_finalizer(rtn, proc do
        rtn.rm_rf
      end)

      rtn
    end

    # --
    # Make a temporary file.
    # @note if you adruptly exit it will not remove the dir.
    # @note this file is removed on exit.
    # @return Pathutil
    # --
    def tmpfile(*args)
      rtn = new(make_tmpname(*args)).tap(&:touch)
      ObjectSpace.define_finalizer(rtn, proc do
        rtn.rm_rf
      end)

      rtn
    end
  end

  # --

  rb_delegate :gcwd, :to => :"self.class"
  rb_delegate :pwd,  :to => :"self.class"

  # --

  rb_delegate :sub,         :to => :@path, :wrap => true
  rb_delegate :chomp,       :to => :@path, :wrap => true
  rb_delegate :gsub,        :to => :@path, :wrap => true
  rb_delegate :=~,          :to => :@path
  rb_delegate :==,          :to => :@path
  rb_delegate :to_s,        :to => :@path
  rb_delegate :freeze,      :to => :@path
  rb_delegate :end_with?,   :to => :@path
  rb_delegate :start_with?, :to => :@path
  rb_delegate :frozen?,     :to => :@path
  rb_delegate :to_str,      :to => :@path
  rb_delegate :"!~",        :to => :@path
  rb_delegate :<=>,         :to => :@path

  # --

  rb_delegate :chmod,        :to => :File, :args => { :after => :@path }
  rb_delegate :lchown,       :to => :File, :args => { :after => :@path }
  rb_delegate :lchmod,       :to => :File, :args => { :after => :@path }
  rb_delegate :chown,        :to => :File, :args => { :after => :@path }
  rb_delegate :basename,     :to => :File, :args => :@path, :wrap => true
  rb_delegate :dirname,      :to => :File, :args => :@path, :wrap => true
  rb_delegate :readlink,     :to => :File, :args => :@path, :wrap => true
  rb_delegate :expand_path,  :to => :File, :args => :@path, :wrap => true
  rb_delegate :realdirpath,  :to => :File, :args => :@path, :wrap => true
  rb_delegate :realpath,     :to => :File, :args => :@path, :wrap => true
  rb_delegate :rename,       :to => :File, :args => :@path, :wrap => true
  rb_delegate :join,         :to => :File, :args => :@path, :wrap => true
  rb_delegate :size,         :to => :File, :args => :@path
  rb_delegate :link,         :to => :File, :args => :@path
  rb_delegate :atime,        :to => :File, :args => :@path
  rb_delegate :ctime,        :to => :File, :args => :@path
  rb_delegate :lstat,        :to => :File, :args => :@path
  rb_delegate :utime,        :to => :File, :args => :@path
  rb_delegate :sysopen,      :to => :File, :args => :@path
  rb_delegate :birthtime,    :to => :File, :args => :@path
  rb_delegate :mountpoint?,  :to => :File, :args => :@path
  rb_delegate :truncate,     :to => :File, :args => :@path
  rb_delegate :symlink,      :to => :File, :args => :@path
  rb_delegate :extname,      :to => :File, :args => :@path
  rb_delegate :zero?,        :to => :File, :args => :@path
  rb_delegate :ftype,        :to => :File, :args => :@path
  rb_delegate :mtime,        :to => :File, :args => :@path
  rb_delegate :open,         :to => :File, :args => :@path
  rb_delegate :stat,         :to => :File, :args => :@path

  # --

  rb_delegate :pipe?,            :to => :FileTest, :args => :@path
  rb_delegate :file?,            :to => :FileTest, :args => :@path
  rb_delegate :owned?,           :to => :FileTest, :args => :@path
  rb_delegate :setgid?,          :to => :FileTest, :args => :@path
  rb_delegate :socket?,          :to => :FileTest, :args => :@path
  rb_delegate :readable?,        :to => :FileTest, :args => :@path
  rb_delegate :blockdev?,        :to => :FileTest, :args => :@path
  rb_delegate :directory?,       :to => :FileTest, :args => :@path
  rb_delegate :readable_real?,   :to => :FileTest, :args => :@path
  rb_delegate :world_readable?,  :to => :FileTest, :args => :@path
  rb_delegate :executable_real?, :to => :FileTest, :args => :@path
  rb_delegate :world_writable?,  :to => :FileTest, :args => :@path
  rb_delegate :writable_real?,   :to => :FileTest, :args => :@path
  rb_delegate :executable?,      :to => :FileTest, :args => :@path
  rb_delegate :writable?,        :to => :FileTest, :args => :@path
  rb_delegate :grpowned?,        :to => :FileTest, :args => :@path
  rb_delegate :chardev?,         :to => :FileTest, :args => :@path
  rb_delegate :symlink?,         :to => :FileTest, :args => :@path
  rb_delegate :sticky?,          :to => :FileTest, :args => :@path
  rb_delegate :setuid?,          :to => :FileTest, :args => :@path
  rb_delegate :exist?,           :to => :FileTest, :args => :@path
  rb_delegate :size?,            :to => :FileTest, :args => :@path

  # --

  rb_delegate :rm_rf,   :to => :FileUtils, :args => :@path
  rb_delegate :rm_r,    :to => :FileUtils, :args => :@path
  rb_delegate :rm_f,    :to => :FileUtils, :args => :@path
  rb_delegate :rm,      :to => :FileUtils, :args => :@path
  rb_delegate :cp_r,    :to => :FileUtils, :args => :@path
  rb_delegate :touch,   :to => :FileUtils, :args => :@path
  rb_delegate :mkdir_p, :to => :FileUtils, :args => :@path
  rb_delegate :mkpath,  :to => :FileUtils, :args => :@path
  rb_delegate :cp,      :to => :FileUtils, :args => :@path

  # --

  rb_delegate :each_child, :to => :children
  rb_delegate :each_entry, :to => :children
  rb_delegate :to_a,       :to => :children

  # --

  rb_delegate :opendir, :to => :Dir, :alias_of => :open
  rb_delegate :relative?, :to => :self, :alias_of => :absolute?, :bool => :reverse
  rb_delegate :regexp_escape, :to => :Regexp, :args => :@path, :alias_of => :escape
  rb_delegate :shellescape, :to => :Shellwords, :args => :@path
  rb_delegate :mkdir, :to => :Dir, :args => :@path

  # --

  alias + join
  alias delete rm
  alias rmtree rm_r
  alias to_path to_s
  alias last basename
  alias entries children
  alias make_symlink symlink
  alias cleanpath_conservative conservative_cleanpath
  alias cleanpath_aggressive aggressive_cleanpath
  alias prepend enforce_root
  alias fnmatch fnmatch?
  alias make_link link
  alias first dirname
  alias rmdir rm_r
  alias unlink rm
  alias / join
end
