package Moodle;

use 5.014;

use strict;
use warnings;

use registry 'Moodle::Library';
use routines;

use Data::Object::Class;
use Data::Object::ClassHas;

our $VERSION = '0.05'; # VERSION

has driver => (
  is => 'ro',
  isa => 'Driver',
  req => 1
);

has migrator => (
  is => 'ro',
  isa => 'Migrator',
  req => 1
);

# METHODS

method content() {
  my $grammar;

  my $driver = $self->driver;
  my $migrator = $self->migrator;

  if ($driver->isa('Mojo::Pg')) {
    $grammar = 'postgres';
  }
  if ($driver->isa('Mojo::SQLite')) {
    $grammar = 'sqlite';
  }
  if ($driver->isa('Mojo::mysql')) {
    $grammar = 'mysql';
  }

  my @sql;

  my $statements = $migrator->statements($grammar);

  for (my $i = 0; $i < @$statements; $i++) {
    my $up_note = "-- @{[$i+1]} up";
    my $up_text = join "\n", map "$_;", @{$statements->[$i][0]};

    push @sql, $up_note, $up_text;

    my $dn_note = "-- @{[$i+1]} down";
    my $dn_text = join "\n", map "$_;", @{$statements->[$i][1]};

    push @sql, $dn_note, $dn_text;
  }

  return join "\n", @sql;
}

method migrate(Maybe[Str] $target) {
  my $driver = $self->driver;
  my $content = $self->content;

  return $driver->migrations->from_string($content)->migrate($target);
}

1;

=encoding utf8

=head1 NAME

Moodle

=cut

=head1 ABSTRACT

Mojo DB Driver Migrations

=cut

=head1 SYNOPSIS

  # migration: step #1

  package Migration::Step1;

  use parent 'Doodle::Migration';

  no warnings 'redefine';

  sub up {
    my ($self, $doodle) = @_;

    my $table = $doodle->table('users');
    $table->primary('id');
    $table->create;

    return $doodle;
  }

  sub down {
    my ($self, $doodle) = @_;

    my $table = $doodle->table('users');
    $table->delete;

    return $doodle;
  }

  # migration: step #2

  package Migration::Step2;

  use parent 'Doodle::Migration';

  no warnings 'redefine';

  sub up {
    my ($self, $doodle) = @_;

    my $table = $doodle->table('users');
    $table->string('email')->create;

    return $doodle;
  }

  sub down {
    my ($self, $doodle) = @_;

    my $table = $doodle->table('users');
    $table->string('email')->delete;

    return $doodle;
  }

  # migration: root

  package Migration;

  use parent 'Doodle::Migration';

  sub migrations {[
    'Migration::Step1',
    'Migration::Step2',
  ]}

  # main program

  package main;

  use Moodle;

  my $self = Moodle->new(
    driver => $main::driver,
    migrator => Migration->new
  );

  # $self->migrate;

=cut

=head1 DESCRIPTION

This package uses L<Doodle> with L<Mojo> database drivers to easily install and
evolve database schema migrations. See L<Doodle::Migration> for help setting up
L<Doodle> migrations, and L<Mojo::Pg>, L<Mojo::mysql> or L<Mojo::SQLite> for
help configuring DB drivers.

=cut

=head1 LIBRARIES

This package uses type constraints from:

L<Moodle::Library>

=cut

=head1 ATTRIBUTES

This package has the following attributes:

=cut

=head2 driver

  driver(Driver)

This attribute is read-only, accepts C<(Driver)> values, and is required.

=cut

=head2 migrator

  migrator(Migrator)

This attribute is read-only, accepts C<(Migrator)> values, and is required.

=cut

=head1 METHODS

This package implements the following methods:

=cut

=head2 content

  content() : Str

This method generates DB migration statements returning a string containing
"UP" and "DOWN" versioned migration strings suitable for use with the migration
feature of Mojo database drivers.

=over 4

=item content example #1

  # given: synopsis

  my $content = $self->content;

=back

=cut

=head2 migrate

  migrate(Maybe[Str] $target) : Object

This method uses the DB migration statements generated by the L</content>
method and installs them using the Mojo database driver. This method returns a
migration object relative to the DB driver used.

=over 4

=item migrate example #1

  # given: synopsis

  my $migrate = $self->migrate;

=back

=cut

=head1 AUTHOR

Al Newkirk, C<awncorp@cpan.org>

=head1 LICENSE

Copyright (C) 2011-2019, Al Newkirk, et al.

This is free software; you can redistribute it and/or modify it under the terms
of the The Apache License, Version 2.0, as elucidated in the L<"license
file"|https://github.com/iamalnewkirk/moodle/blob/master/LICENSE>.

=head1 PROJECT

L<Wiki|https://github.com/iamalnewkirk/moodle/wiki>

L<Project|https://github.com/iamalnewkirk/moodle>

L<Initiatives|https://github.com/iamalnewkirk/moodle/projects>

L<Milestones|https://github.com/iamalnewkirk/moodle/milestones>

L<Contributing|https://github.com/iamalnewkirk/moodle/blob/master/CONTRIBUTE.md>

L<Issues|https://github.com/iamalnewkirk/moodle/issues>

=cut
