package FixMyStreet::PhotoStorage::S3;

use Moose;
use parent 'FixMyStreet::PhotoStorage';

use Net::Amazon::S3;
use Try::Tiny;


has client => (
    is => 'ro',
    lazy => 1,
    default => sub {
        my $key = FixMyStreet->config('PHOTO_STORAGE_OPTIONS')->{ACCESS_KEY};
        my $secret = FixMyStreet->config('PHOTO_STORAGE_OPTIONS')->{SECRET_KEY};

        my $s3 = Net::Amazon::S3->new(
            aws_access_key_id     => $key,
            aws_secret_access_key => $secret,
            retry                 => 1,
        );
        return Net::Amazon::S3::Client->new( s3 => $s3 );
    },
);

has bucket => (
    is => 'ro',
    lazy => 1,
    default => sub {
        shift->client->bucket( name => FixMyStreet->config('PHOTO_STORAGE_OPTIONS')->{BUCKET} );
    },
);

has region => (
    is => 'ro',
    lazy => 1,
    default => sub {
        return FixMyStreet->config('PHOTO_STORAGE_OPTIONS')->{REGION};
    },
);

has prefix => (
    is => 'ro',
    lazy => 1,
    default => sub {
        my $self = shift;
        my $prefix = FixMyStreet->config('PHOTO_STORAGE_OPTIONS')->{PREFIX};
        return "" unless $prefix;
        $prefix =~ s#/$##;
        return "$prefix/";
    },
);

sub init {
    my $self = shift;

    return 1 if $self->_bucket_exists();

    if ( FixMyStreet->config('PHOTO_STORAGE_OPTIONS')->{CREATE_BUCKET} ) {
        my $name = $self->bucket->name;
        try {
            $self->client->create_bucket(
                name => $name,
                location_constraint => $self->region,
            );
        } catch {
            warn "\x1b[31mCouldn't create S3 bucket '$name'\x1b[0m\n";
            return;
        };

        return 1 if $self->_bucket_exists();

        warn "\x1b[31mCouldn't create S3 bucket '$name'\x1b[0m\n";
        return;
    } else {
        my $bucket = $self->bucket->name;
        warn "\x1b[31mS3 bucket '$bucket' doesn't exist and CREATE_BUCKET is not set.\x1b[0m\n";
        return;
    }
}

sub _bucket_exists {
    my $self = shift;
    my $name = $self->bucket->name;
    my @buckets = $self->client->buckets;
    return grep { $_->name eq $name } @buckets;
}

sub get_object {
    my ($self, $key) = @_;
    return $self->bucket->object( key => $key );
}

sub store_photo {
    my ($self, $photo_blob) = @_;

    my $type = $self->detect_type($photo_blob) || 'jpeg';
    my $fileid = $self->get_fileid($photo_blob);
    my $key = $self->prefix . "$fileid.$type";

    my $object = $self->get_object($key);
    $object->put($photo_blob);

    return $key;
}


sub retrieve_photo {
    my ($self, $key) = @_;

    my $object = $self->get_object($key);
    if ($object->exists) {
        return ($object->get);
    }

}

1;
