#! /bin/false

# Copyright (C) 2016-2018 Guido Flohr <guido.flohr@cantanea.com>,
# all rights reserved.

# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

package Qgoda::Analyzer;
$Qgoda::Analyzer::VERSION = 'v0.9.3';
use strict;

use Locale::TextDomain qw('qgoda');
use Date::Parse;
use File::Spec;
use File::Basename qw(fileparse);
use Scalar::Util qw(reftype);

use Qgoda::Util qw(empty yaml_error front_matter lowercase collect_defaults
                   normalize_path strip_suffix merge_data slugify
                   safe_yaml_load);
use Qgoda::Util::Date;
use Qgoda::Util::Translate qw(translate_front_matter);

sub new {
    my ($class) = @_;

    bless {}, $class;
}

sub setup {
    shift;
}

sub analyze {
    my ($self, $asset, $site, $precious) = @_;

    my $qgoda = Qgoda->new;

    my $path = $asset->getPath;
    stat $path or die __x("cannot read '{filename}': {error}",
                          filename => $path, error => $!);
    my $config = $qgoda->config;
    my $meta = collect_defaults $asset->getRelpath, $config->{defaults};

    my $front_matter = front_matter $path;
    my $front_matter_data;
    if (defined $front_matter) {
        $front_matter_data = safe_yaml_load $front_matter;
    } else {
        $front_matter_data->{raw} = 1;
    }

    merge_data $meta, $front_matter_data;

    delete $meta->{path};
    delete $meta->{relpath};
    delete $meta->{reldir};

    merge_data $asset, $meta;
    if (!empty $asset->{master}) {
        translate_front_matter $asset, $front_matter_data;
    }

    merge_data $asset, $precious if $precious;

    $self->__fillMeta($asset) if !$asset->{raw};

    my %build_options = $qgoda->buildOptions;
    if ($asset->{draft} && !$build_options{drafts}) {
        my $logger = $qgoda->logger;
        $logger->debug(__x("skipping draft '{relpath}'",
                           relpath => $asset->getRelpath));
        $site->removeAsset($asset);
    }

    my $now = time;
    if ($asset->{date} > $now && !$build_options{future}) {
        my $logger = $qgoda->logger;
        $logger->debug(__x("skipping future document '{relpath}'",
                           relpath => $asset->getRelpath));
        $site->removeAsset($asset);
    }

    return $self;
}

sub __fillMeta {
    my ($self, $asset) = @_;

    my $qgoda = Qgoda->new;
    my $logger = $qgoda->logger;
    my $config = $qgoda->config;
    my $site = $qgoda->getSite;

    my $date = $asset->{date};
    if (defined $date) {
        if ($date !~ /^-?[1-9][0-9]*$/) {
            $date = str2time $date;
            if (!defined $date) {
                $logger->error(__x("{filename}: cannot parse date '{date}'",
                                   date => $asset->{date}));
            }
        }
    }

    if (!defined $date) {
        my @stat = stat $asset->getPath;
        if (!@stat) {
            $logger->error(__x("cannot stat '{filename}': {error}",
                               filename => $asset->getPath, error => $!));
            $date = time;
        } else {
            $date = $stat[9];
        }
    }

    $asset->{date} = Qgoda::Util::Date->newFromEpoch($date);

    $self->__fillPathInformation($asset, $site);

    $asset->{title} = $asset->{basename} if !exists $asset->{title};
    $asset->{slug} = $self->__slug($asset);

    $asset->{view} = $site->getMetaValue(view => $asset);
    $asset->{type} = $site->getMetaValue(type => $asset);

    return $self;
}

sub __slug {
    my ($self, $asset) = @_;

    return slugify $asset->{title};
}

sub __fillPathInformation {
    my ($self, $asset, $site) = @_;

    my $relpath = $asset->getRelpath;
    my ($filename, $directory) = fileparse $relpath;

    $asset->{filename} = $filename;

    $directory = normalize_path $directory;
    $directory = '' if '.' eq $directory;
    $asset->{directory} = $directory;

    my ($basename, @suffixes) = strip_suffix $filename;
    $asset->{basename} = $basename;

    # For migration from Jekyll sites.
    $basename =~ s/^[0-9]{4}-[0-9]{2}-[0-9]{2}-//;
    $asset->{basename_nodate} = $basename;

    if (empty $asset->{chain}) {
        my $trigger = $site->getTrigger(@suffixes);
        if (!empty $trigger) {
            my ($chain, $name) = $site->getChainByTrigger($trigger);
            $asset->{chain} = $name if $chain;
            if ($chain && exists $chain->{suffix}) {
                for (my $i = $#suffixes; $i >= 0; --$i) {
                    if ($suffixes[$i] eq $trigger) {
                        $suffixes[$i] = $chain->{suffix};
                        last;
                    }
                }
            }
        }
    }

    $asset->{suffixes} = \@suffixes;
    if (@suffixes) {
        $asset->{suffix} = '.' . join '.', @suffixes;
    }

    $asset->{location} = $site->getMetaValue(location => $asset);
    $asset->{permalink} = $site->getMetaValue(permalink => $asset);

    if (Qgoda->new->config->{'case-sensitive'}) {
        $asset->{location} = lc $asset->{location};
        $asset->{permalink} = lc $asset->{permalink};
    }

    $asset->{index} = $site->getMetaValue(index => $asset);

    return $self;
}

1;
