package DX::Lib::FS::Action::CreateFile;

use aliased 'DX::Lib::FS::Fact::FileContent';
use aliased 'DX::Lib::FS::Fact::PathStatus';
use aliased 'DX::Lib::FS::Fact::PathStatusInfo';
use Fcntl qw(O_CREAT O_WRONLY);
use Moo;

with 'DX::Role::Action';

has path => (is => 'ro', required => 1);

has mode => (is => 'ro', predicate => 1);

has data => (is => 'ro', default => sub { '' });

sub expected_effect {
  my ($self) = @_;
  return +(path_status => PathStatus->new(
    path => $self->path,
    info => PathStatusInfo->new(
      is_file => 1,
      mode => ($self->has_mode ? $self->mode : '')
    )
  ), file_content => FileContent->new(
    path => $self->path,
    data => $self->data,
  ));
}

sub _do_run {
  my ($self) = @_;
  my $fh;
  if ($self->has_mode) {
    my $umask = umask(0000);
    sysopen(
      $fh, $self->path, O_CREAT | O_WRONLY, oct($self->mode)
    ) or do { umask($umask); die "Couldn't create ${\$self->path}: $!" };
    umask($umask);
  } else {
    sysopen($fh, $self->path, O_CREAT | O_WRONLY)
      or die "Couldn't create ${\$self->path}: $!";
  }
  print $fh $self->data if length($self->data);
  +(path_status => PathStatus->new(path => $self->path));
}

1;
