package Git::Repository::File;
our $VERSION = '0.001'; # VERSION: generated by DZP::OurPkgVersion

use overload (
    q[""] => 'stringify',
    'bool' => 'boolify',
    fallback => 1,
);

use Path::Class::File qw();

sub new {
    my $class = shift;
    my $repo = shift;
    my $file = pop;
    my @dirs = @_;

    unless ($repo->work_tree) {
        die 'work_tree';
    }
    unless ($file->isa('Path::Class::File')) {
        $file = Path::Class::File->new($repo->work_tree, @dirs, $file);
    }

    return bless {
        file => $file,
        repo => $repo,
    }, $class;
}

sub add {
    my $self = shift;
    my @args = @_;
    $self->{repo}->run('add', @args, $self->{file});
    return $self;
}

sub commit {
    my $self = shift;
    my @args = @_;
    $self->{repo}->run('commit', @args, $self->{file});
    return $self;
}

sub remove {
    my $self = shift;
    my @args = @_;
    $self->{repo}->run('rm', @args, $self->{file});
    return $self;
}

sub wrapped_methods {
    my @wrapped_methods = qw(
        absolute
        basename
        boolify
        cleanup
        components
        copy_to
        dir
        is_absolute
        is_dir
        is_relative
        lstat
        move_to
        opena
        openr
        openw
        parent
        relative
        resolve
        slurp
        spew
        stat
        stringify
        touch
        volume
    );
    return @wrapped_methods;
}

for my $name (wrapped_methods()) {
    my $new_sub = sub {
        my $self = shift;
        my @args = @_;

        my $wantscalar = (defined wantarray && !wantarray);
        if ($wantscalar) {
            my $result = $self->{file}->$name(@args);
            if ($result && $result->isa('Path::Class::File')) {
                return __PACKAGE__->new($self->{repo}, $result);
            } else {
                return $result;
            }
        } else {
            return $self->{file}->$name(@args);
        }
    };

    my $fullname = join('::', __PACKAGE__, $name);
    *{$fullname} = $new_sub;
}

1;

__END__

=pod

=head1 NAME

Git::Repository::File - Objects representing files in a Git::Repository

=head1 VERSION

version 0.001

=head1 SYNOPSIS

    use Git::Repository qw(File);

    my $repo = Git::Repository->new();
    my $file = $repo->file('lib', 'Git', 'Repository', 'File.pm');

    # provides Path::Class::File API
    $file->openw->say('line one');

    # also provides add, commit, and remove
    $file->add;
    $file->commit('-m', "commit $file");
    $file->remove;
    $file->commit('-m', "removed $file");

=head1 DESCRIPTION

C<Git::Repository::File> mostly wraps <Path::Class::File>.

=head1 METHODS

L<Git::Repository::File|Git::Repository::File> adds the
following methods on to a L<Path::Class::File|Path::Class::File>-like API:

=head2 add(@options)

Does something....

=head1 SEE ALSO

L<Git::Repository|Git::Repository>,
L<Git::Repository::Plugin::File|Git::Repository::Plugin::File>,
L<Path::Class::File|Path::Class::File>

=head1 AUTHOR

Nathaniel G. Nutter <nnutter@cpan.org>

=head1 COPYRIGHT

Copyright 2013 - Nathaniel G. Nutter

=head1 LICENSE

This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself.

=cut
