#!/usr/bin/perl
use strict;
use warnings;

open my $ofp, ">", "filelist.mk";

sub ADDLINE($) { local $\="\n"; print $ofp @_; }

sub find_srcfiles {
    my $dir = shift;
    my $c_src = qx(find $dir -iname "*.c");
    my $h_src = qx(find $dir -iname "*.h");
    my $cxx_src = qx(find $dir -iname "*.cc");
    my @ret;
    push @ret, split(' ', $c_src), split(' ', $h_src), split(' ', $cxx_src);
    return @ret;
}

sub fmt_filelist {
    return join(" \\\n    ", @_);
}

sub add_target {
    my ($name,$options) = @_;
    print $ofp "noinst_LTLIBRARIES += $name.la\n";
    foreach my $var (qw(SOURCES DEPENDENCIES LIBADD)) {
        ADDLINE "${name}_la_${var}=";
    }
    my %flag_h = (CFLAGS => '', CPPFLAGS => '');
    if ($options && $options->{nocore}) {
        %flag_h = map { $_ => "\$(AM_NOWARN_${_})" } keys %flag_h;
    } else {
        %flag_h = map { $_ => "\$(libcouchbase_la_${_})" } keys %flag_h;
    }

    while (my ($k,$v) = each %flag_h) {
        ADDLINE "${name}_la_${k}=$v";
    }
}

sub add_dependency {
    my ($name,$depname) = @_;
    ADDLINE "${name}_la_DEPENDENCIES += ${depname}.la";
    ADDLINE "${name}_la_LIBADD += ${depname}.la";
}

sub add_sources {
    my ($tgt,@src) = @_;
    ADDLINE "${tgt}_la_SOURCES += ".fmt_filelist(@src);
}

sub condition($&;&) {
    my ($name,$fn,$elsefn) = @_;
    ADDLINE "if $name";
    $fn->();
    if ($elsefn) {
        ADDLINE "else";
        $elsefn->();
    }
    ADDLINE "endif";
}

printf $ofp "# This file generated by %s on %s\n", $0, scalar localtime();

my @PKGINCLUDE_HEADERS;

# Find the main source files
push @PKGINCLUDE_HEADERS,
    find_srcfiles("include/libcouchbase"),
    "include/libcouchbase/configuration.h",
    "plugins/io/libuv/libuv_io_opts.h",
    "plugins/io/libev/libev_io_opts.h",
    "plugins/io/libevent/libevent_io_opts.h",
    "plugins/io/select/select_io_opts.h",
    "plugins/io/iocp/iocp_iops.h";

my %tmp = map { $_ => 1 } @PKGINCLUDE_HEADERS;
@PKGINCLUDE_HEADERS = keys %tmp;

# @PKGINCLUDE_HEADERS = grep { $_ !~ /configuration\.h/ } @PKGINCLUDE_HEADERS;

@PKGINCLUDE_HEADERS = grep { $_ !~ /plugins/ } @PKGINCLUDE_HEADERS;
ADDLINE 'pkginclude_HEADERS = '.fmt_filelist(@PKGINCLUDE_HEADERS);
ADDLINE 'ioplugindir = $(includedir)/libcouchbase/plugins/io';
ADDLINE 'ioplugin_HEADERS ='.fmt_filelist(find_srcfiles('include/libcouchbase/plugins/io'));

# Filter out generated files
add_sources('libcouchbase', grep { $_ !~ m,src/ssl, && $_ !~ m,src/config.h, && $_ !~ m,src/probes.h, } find_srcfiles('src'));
add_sources('libcouchbase', find_srcfiles('plugins/io/select'));
add_sources('libcouchbase', find_srcfiles('contrib/genhash'));
add_sources('libcouchbase', find_srcfiles('contrib/http_parser'));
add_sources('libcouchbase', find_srcfiles('contrib/cJSON'));
add_sources('libcouchbase', find_srcfiles('include/memcached'));

add_target('libcbsasl', {nocore=>1});
add_sources('libcbsasl', find_srcfiles('contrib/cbsasl'));
add_dependency('libcouchbase', 'libcbsasl');

condition 'ENABLE_SSL', sub {
    add_sources('libcouchbase', find_srcfiles('src/ssl'));
};
condition 'ENABLE_SNAPPY', sub {
    add_target('liblcbsnappy');
    add_dependency('libcouchbase', 'liblcbsnappy');

    condition 'BUILD_STATIC_SNAPPY', sub {
        add_sources('liblcbsnappy', find_srcfiles('contrib/snappy'));
    }, sub {
        add_sources('liblcbsnappy', 'config/dummy-c.c');
    };

};

condition 'HAVE_CXX', sub {
    condition 'BUILD_TOOLS', sub {
        add_target('libcliopts', { nocore => 1 });
        add_sources('libcliopts', find_srcfiles('contrib/cliopts'));
        add_target('liblcbtools');
        add_sources('liblcbtools', find_srcfiles('tools/common'));
        add_dependency("liblcbtools", "libcliopts");
    };
};

# Write the EXTRA_DIST
ADDLINE 'EXTRA_DIST =';
