package Distribution::DB::Item::DistributionProcess;
use strict;

use lib '/app/tools/common/lib';
use base 'Common::DB::Item';
use Common::Assert;
use Data::Dumper;

use constant kTable => 'distribution_process';
use constant kDB    => Common::DB::Item::kClientDB;

sub LookupServiceID {
    my $self                  = shift;
    my $distributionProcessID = shift;
    assert($distributionProcessID);

    my $dbo = Common::RSApp::GetClientDB();
    my $sql =
        "SELECT service_id FROM "
      . kTable
      . " INNER JOIN product_distribution USING (distribution_process_id) "
      . "WHERE distribution_process.distribution_process_id = ? ";

    my $sth = $dbo->DoCmdWithPlaceholders( $sql, [$distributionProcessID] );
    my ($service_id) = $sth->fetchrow_array();
    return $service_id;
}

sub SetDeliveryDate {
    my $class                 = shift;
    my $distributionProcessID = shift;
    assert($distributionProcessID);

    my $dbo = Common::RSApp::GetClientDB();
    my $sql =
        "UPDATE product_distribution SET delivery_date = NOW(), "
      . 'denied = NULL AND invalid <> 1 '
      . "WHERE distribution_process_id = "
      . $dbo->DBQuote($distributionProcessID);

    $dbo->DoCmd($sql);
}

sub LookupServiceByJob {
    my $self                  = shift;
    my $distributionProcessID = shift;
    my $clientID              = shift;

    assert($distributionProcessID);

    my $dbo = Common::RSApp::GetCommonDB();
    my $sql =
      "SELECT subclass FROM distribution_job INNER JOIN job USING (job_id) " . "WHERE distribution_process_id = ? AND client_id = ?";

    my $sth = $dbo->DoCmdWithPlaceholders( $sql, [ $distributionProcessID, $clientID ] );
    my ($name) = $sth->fetchrow_array();
    return $name;
}

sub LookupQueueDate {
    my $self                  = shift;
    my $distributionProcessID = shift;
    my $clientID              = shift;

    assert($distributionProcessID);

    my $dbo = Common::RSApp::GetCommonDB();
    my $sql =
      "SELECT MIN(queue_date) FROM distribution_job INNER JOIN job USING (job_id) " . "WHERE distribution_process_id = ? AND client_id = ?";

    my $sth = $dbo->DoCmdWithPlaceholders( $sql, [ $distributionProcessID, $clientID ] );
    my ($date) = $sth->fetchrow_array();
    return $date;
}

sub LookupEndDate {
    my $self                  = shift;
    my $distributionProcessID = shift;
    my $clientID              = shift;

    assert($distributionProcessID);

    my $dbo = Common::RSApp::GetCommonDB();
    my $sql =
        "SELECT MAX(end_date) FROM distribution_job INNER JOIN job USING (job_id) "
      . "WHERE distribution_process_id = ? AND client_id = ? "
      . "GROUP BY class ORDER BY class";

    my $sth = $dbo->DoCmdWithPlaceholders( $sql, [ $distributionProcessID, $clientID ] );
    my ($date) = $sth->fetchrow_array();
    return $date;
}

sub LookupDelivering {
    my $self                  = shift;
    my $distributionProcessID = shift;
    my $clientID              = shift;

    assert($distributionProcessID);

    my $dbo = Common::RSApp::GetCommonDB();
    my $sql = "SELECT count(*) FROM distribution_job INNER JOIN job USING (job_id) "
      . "WHERE distribution_process_id = ? AND client_id = ? AND class = 'Delivery'";

    my $sth = $dbo->DoCmdWithPlaceholders( $sql, [ $distributionProcessID, $clientID ] );
    my ($count) = $sth->fetchrow_array();
    return $count ? 1 : 0;
}

sub LookupState {
    my $class                 = shift;
    my $distributionProcessID = shift;
    my $clientID              = shift;

    my $dbo = Common::RSApp::GetCommonDB();
    my $sql =
        "SELECT distribution_job_status.status "
      . "FROM distribution_job "
      . "INNER JOIN job USING (job_id) "
      . "LEFT JOIN distribution_job_status ON ( "
      . "distribution_job.distribution_process_id = distribution_job_status.distribution_process_id AND "
      . "job.client_id = distribution_job_status.client_id ) "
      . "WHERE distribution_job.distribution_process_id = "
      . $dbo->DBQuote($distributionProcessID) . " AND "
      . "job.client_id = "
      . $dbo->DBQuote($clientID) . " "
      . "GROUP BY distribution_job.distribution_process_id, job.client_id";

    Common::Log::Debug("QUERY: $sql");
    my $sth = $dbo->DoCmd($sql);
    my ($state) = $sth->fetchrow_array();
    return $state;
}

sub GetState {
    my $self                  = shift;
    my $distributionProcessID = shift;
    my $clientID              = shift;

    my $dbo = Common::RSApp::GetCommonDB();
    my $sql =
        'SELECT job.job_id, queue_date, start_date, end_date, exit_code, '
      . ' if( start_date, 1, 0 ) as running '
      . 'FROM distribution_job INNER JOIN job USING (job_id) '
      . 'WHERE distribution_process_id = '
      . $dbo->DBQuote($distributionProcessID) . ' AND '
      . 'client_id = '
      . $dbo->DBQuote($clientID) . ' '
      . 'ORDER BY job_id DESC '
      . 'LIMIT 1';

    Common::Log::Debug("QUERY: $sql");

    my $sth = $dbo->DoCmd($sql);
    my $row = $sth->fetchrow_hashref();

    return 'done'
      if ( defined( $row->{exit_code} ) && $row->{exit_code} == 0 );

    return 'failed'
      if ( defined( $row->{exit_code} ) );

    return 'running'
      if ( $row->{running} );

    return "pending";
}

sub setDenied {
    my $self = shift;
    my $id   = shift;
    my $msg  = shift || "Unknown Error";

    assert($id);

    my $dbo = Common::RSApp::GetClientDB();
    my $sql = "UPDATE product_distribution SET denied = " . $dbo->DBQuote($msg) . " WHERE distribution_process_id = " . $dbo->DBQuote($id);

    $dbo->DoCmd($sql);
}

1;
