# Copyright (c) 2023 Yuki Kimoto
# MIT License

class File::Basename::Instance::Unix extends File::Basename::Instance {
  version_from File::Basename;
  
  allow File::Basename;
  allow File::Basename::Instance;
  
  use Re;
  
  # Class Methods
  private static method new : File::Basename::Instance::Unix () {
    
    my $self = new File::Basename::Instance::Unix;
    
    return $self;
  }
  
  # Instance Methods
  protected method fileparse : string[] ($path : string) {
    unless ($path) {
      die "The \$path must be defined";
    }
    
    my $dirpath = (string)undef;
    my $basename = (string)undef;
    
    if (my $match = Re->m($path, "(?s)^(.*/)?(.*)")) {
      $dirpath = $match->cap1;
      $basename = $match->cap2;
    }
    
    unless (length $dirpath) {
      $dirpath = "./";
    }
    
    return [$basename, $dirpath, ""];
  }
  
  protected method basename : string ($path : string) {
    unless ($path) {
      die "The \$path must be defined";
    }
    
    $path = $self->_strip_trailing_sep($path);
    
    my $fileparse = $self->fileparse($path);
    
    my $basename = $fileparse->[0];
    my $dirname = $fileparse->[1];
    
    if (!length $basename) {
      $basename = $dirname;
    }
    
    return $basename;
  }
  
  protected method dirname : string ($path : string) {
    unless ($path) {
      die "The \$path must be defined";
    }
    
    my $fileparse = $self->fileparse($path);
    
    my $basename = $fileparse->[0];
    my $dirname = $fileparse->[1];
    
    $dirname = $self->_strip_trailing_sep($dirname);
    
    unless (length $basename) {
      my $fileparse_again = $self->fileparse($dirname);
      $dirname = $fileparse_again->[1];
      $dirname = $self->_strip_trailing_sep($dirname);
    }
    
    return $dirname;
  }
  
  protected method _strip_trailing_sep : string ($path : string)  {
    
    $path = copy $path;
    
    Re->s((mutable string)$path, "(?s)(.)/*\z", method : string ($re : Regex, $match : Regex::Match) {
      return $match->cap1;
    });
    
    return $path;
  }
  
}