#! /usr/bin/perl -T

# Get a blob from the database and return it as a png image.

my $dir;
BEGIN {
    use Cwd qw(abs_path);
    $dir = abs_path(__FILE__);
    $dir =~ /(.*)(\/.*\/.*\/.*\..*)$/;
    $dir = $1;
    unshift(@INC, $dir . "/lib");
}

use strict;
use warnings;
use CGI qw(:standard -utf8);
use Database;
use DBI;
use Encode qw(encode);
use File::Basename qw(basename dirname);
use HTML::Entities;
use HTML::FromText;

use CGIParameters qw(read_cgi_parameters);
use HTMLGenerator qw(error_page);
use RestfulDB::CGI qw( save_cgi_parameters );
use RestfulDB::Defaults;
use RestfulDB::DBSettings qw( get_database_settings );

# STDIN must NOT be set to binmode "UTF-8", since CGI with the '-utf8'
# flag handles this.
#binmode( STDOUT, "utf8" );

binmode( STDERR, "utf8" );

my $page_level = 3;

$ENV{PATH} = ""; # Untaint and clean PATH

# Path to database directory for SQlite3 databases:
my $db_dir = $dir . "/db";

my $cgi = new CGI;
my $format = 'html';

eval {

    my( $base_uri, $query_string ) = split /\?/, $ENV{REQUEST_URI};

    my( $params, $changed );
    eval {
        ( $params, $changed ) =
            read_cgi_parameters( $cgi,
                                 \%RestfulDB::Defaults::CGI_parameters,
                                 { query_string => $query_string } );
    };
    InputException->throw( $@ ) if $@;

    my %params = %$params;

    if( $params{debug} && $params{debug} eq 'save' ) {
        save_cgi_parameters( $db_dir );
    }

    $format = $params{format} if $changed->{format};

    my %db_settings = get_database_settings( \%params, \%ENV,
                                             { db_dir => $db_dir, level => $page_level });

    my $db_user = $db_settings{db_user};
    my $db_name = $db_settings{db_name};
    my $db_path = $db_settings{db_path};
    my $db_table = $db_settings{db_table};
    my $db_engine = $db_settings{db_engine};
    my $record_id = $db_settings{record_id};
    my $record_column = $db_settings{record_column};

    my $remote_user = $db_settings{remote_user_for_print};

    my $db_settings = {
        content_db => { DB => $db_path,
                        engine => $db_engine,
                        user => $db_user },
    };

    my $db = Database->new( $db_settings );
    $db->connect( { RaiseError => 1, AutoCommit => 1 } );

    my $default_mime_type = 'image/png'; # Default MIME type

    my $column_properties = $db->get_column_properties( $db_table );

    # If supplied ID is not a real ID, other external keys should be
    # checked:
    $record_id = $db->get_id_by_extkey( $db_table, $record_id );

    my $mime_type;
    if( exists $column_properties->{mimetype}{$record_column} ) {
        my $mime_type_column = $column_properties->{mimetype}{$record_column};
        $mime_type = $db->get_column_data( $db_table, $record_id,
                                           $mime_type_column );
    }

    my $blob = $db->get_column_data( $db_table, $record_id, $record_column );

    # filename column may not be present, silently skipping such cases:
    my $filename;
    eval {
        $filename = $db->get_column_data( $db_table, $record_id, 'filename' );
    };

    if( defined $blob ) {
        if( !$mime_type ) {
            use File::LibMagic;
            use IO::String;

            my $magic  = File::LibMagic->new();
            my $info   = $magic->info_from_string( $blob );
            $mime_type = $info->{mime_with_encoding};
            if( !$mime_type ) {
                $mime_type = $default_mime_type;
            }
        }
        print $cgi->header( -type => $mime_type,
                            -Content_length => length $blob,
                            -charset => 'UTF-8',
                            -attachment => encode( 'UTF-8', $filename ) ) .
              $blob;
    } else {
        print $cgi->header( -status => '204 No Content',
                            -charset => 'UTF-8' );
    }
};

if( $@ ) {
    error_page( $cgi, $@, $page_level );
}
