use strict;
use warnings;
package Acme::CatFS;

# ABSTRACT: Fuse filesystem with a random pic of a cat

use feature qw(say state);
use Carp;
use Try::Tiny;
use LWP::Simple;
use Fuse::Simple;

use Moo;
use MooX::Options;
use Types::Path::Tiny qw(Dir);

option mountpoint => ( 
  is       => 'ro', 
  isa      => Dir,
  required => 1,
  format   => 's',
  coerce   => Dir->coercion,
  doc      => 'mount point for catfs (should be a directory). Required.',

option cat_url => (
  is      => 'ro',
  format  => 's',
  default => sub {
  doc     => 'url used to find a random pic of a cat (default',

option cat_file => (
  is      => 'ro',
  format  => 's',
  default => sub { 'cat.jpg' },
  doc     => 'name of the file (default is cat.jpg)',

option forking => (
  is  => 'ro',
  doc => 'if enable, will fork and exit (default false)',

option debug => (
  is  => 'ro',
  doc => 'if enable, will run Fuse::Simple in debug mode (default false)',

option cached => (
  is  => 'ro',
  doc => 'if enable, will cached the picture instead choose another each open (default false)',

sub _get_cat_picture {
  my $self = shift;
  state $cached_content;
  if($self->cached && $cached_content){
    return $cached_content;

  my $content = try { 
  } catch {
    carp $_ if $self->debug;

    $cached_content = $content


sub run {
  my ($self) = @_;

    fork and exit  

  my $mountpoint = $self->mountpoint;
  my $cat_file   = $self->cat_file;

  say "Initializing Fuse mountpoint '$mountpoint'... ";

    mountpoint => $mountpoint,
    debug      => $self->debug,
    '/'        => {
      $cat_file => sub {

   say "Don't forget run 'fusermount -u <mountpoint>'"

=head1 NAME



  Acme::CatFS->new(mountpoint => '/tmp/catfs', debug => 0, cat_file => 'kitten.jpg')->run();


Acme::CatFS will create a Fuse mountpoint and generate one virtual file, a random image of a cat. Will return a different image each time.

It is the equivalent to:

    mountpoint => $mountpoint,
    "/"        => {
      'cat.jpg' => sub {

=head1 METHODS

=head2 run

Will initialize the Fuse mountpoint.

=head1 SCRIPT

You can call acme-catfs helper script in you command line to easily create the mountpoint. Try C<acme-catfs -h> to see the options.


=head2 mountpoint

Specify the directory mountpoint for Fuse. Should be an empty directory.

=head2 cat_url

Specify the url for the random pic of cat. Default is '' service.

=head2 cat_file

Specify the name of the file. Default is 'cat.jpg'

=head2 debug

If true, will run Fuse::Simple::main in debug mode.

=head2 forking

If true, we will fork then exit.

=head2 cached

if true, we will cache the cat picture instead download a new one.

=head1 SEE ALSO

L<Fuse::Simple> and L<Fuse>


Thanks to Julia Evans (twitter => @b0rk, blog => L<>) with the original idea and support on twitter. And Nick Waterman (pause => NOSEYNICK) by L<Fuse::Simple> module - it is awesome!

=head1 AUTHOR

Tiago Peczenyj, E<lt>tiago.peczenyj@gmail.comE<gt>


Copyright (C) 2014 by Tiago Peczenyj

This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself, either Perl version 5.10.0 or,
at your option, any later version of Perl 5 you may have available.