package Standup::Diary;

use v5.28;

use Config::Tiny;
use Object::Pad ':experimental';
use Path::Tiny;

use Standup::Role::Project;
use Standup::Role::Date;
use Standup::Diary::Template;

our $VERSION = '0.07_02';
$VERSION =~ tr/_//d;

class Standup::Diary :does( Date ) :does( Project ) {

  field $config :accessor :param { Config::Tiny->read('diary.conf') };

  field $daily_data_path :accessor;

  field $data_dir :param :reader;

  field $template :writer :accessor;

  method init_daily_data_path ($path) {
    $daily_data_path = $data_dir ?
      path( $data_dir . '/' . $path ) :
      path( $config->{data}->{path} . '/' . $path );
  }

  method write {

    $self->set_template( Standup::Diary::Template->new(
      date         => $self->date,
      project_name => $self->project_name
    ));

    if ( $self->should_create_dir ) {
      say "$daily_data_path should be created";
      $self->create_directories_tree;
    } else {
      $self->init_daily_data_path($self->build_path($self->date->ymd('/')));
    }

    my $file_path = path($self->build_full_file_path);

    path($file_path)->spew_utf8($template->render) and say "Diary entry created $file_path"
      unless $file_path->exists and say "Entry already exist";

  }

  # TODO should have a Standup::Diary::Path object for those
  method build_full_file_path {
    return $daily_data_path .
      '/' .
      $self->date->ymd .
      '_' .
      lc $self->project_name .
      '.md';
  }

  method build_path ($date) {
    my ($path) = $date =~ m/ \d{4} \/ \d{2} /gx ;
    return $path;
  }

  method should_create_dir {
    $self->init_daily_data_path($self->build_path($self->date->ymd('/')));
    return $daily_data_path->exists ? 0 : 1;
  }

  method create_directories_tree {

    if ($self->date->day_of_month == 1 ) {
      # TODO if first day of the month
      # Create a Priorities file
    }

    my @created = $daily_data_path->mkpath;
    say "Created $daily_data_path" if @created;
  }
}

=encoding utf8

=head1 NAME

Standup::Diary - Manage a simple journal in Markdown files

=head1 SYNOPSIS

  carton exec perl ./script/diary.pl --data-dir /home/smonff/diary/ --project-name SeriousWork

=head1 DESCRIPTION

This module helps you to keep a directory of organized daily notes.

It provides a way to customize the notes template.

=head2 FUN FACTS

I use it daily at work since 2021 to prepare and read notes for daily standups.

It's also my pet project for Perl's Corinna implementation of the core OOP
features. C<Diary.pm> use C<Object::Pad>, though, that is the test bed for the
core features.

=head1 INSTALLATION

  # Install a Perl module manager
  apt install carton

  git clone git@codeberg.org:smonff/Diary.git

  cd Diary

  # Install CPAN dependencies
  carton install

=head1 HOW I USE IT?

I set an alias in my C<.bashrc>. Should also work in your own-favorite-shell:

  alias diary="cd ~/project/diary/ && carton exec perl ./script/diary.pl --data-dir /home/smonff/diary --project-name SeriousWork && cd -";

Each morning, before my work standup, I run C<diary>. It create a Markdown file
in the specified C<--project-name> directory. I then edit my thoughts with an
editor.

=head1 METHODS

=head2 init_daily_data_path

Helper that initialize C<$daily_data_path> with a C<Path::Tiny> instance
for the current day diary entry.

  # foo/2022/03 (Path::Tiny)
  $self->init_daily_data_path($self->build_path)

=head2 render()

=head2 write()

=head1 LICENSE

Copyright 2022-2024 Sebastien Feugère

This library is free software; you can redistribute it and/or modify it under
the Artistic License 2.0.

See L<perlartistic>.

=head1 AUTHOR

Sébastien Feugère - seb@feugere.net

=head1 SEE ALSO

=over 2

=item L<StandupGenerator|https://metacpan.org/release/JTREEVES/StandupGenerator-0.5/source/README.md>

On the CPAN, this is pretty much all what I found. I like the spirit of this
one.

=item L<Almanac|https://codeberg.org/jameschip/almanac>

A similar effort written in Bash.

=back

=cut
