#!/usr/bin/perl

use strict;
use FindBin qw($Bin);
use Getopt::Long;

sub usage {
    die "Usage: dev-server [--wipe] [--mongo|--memory] [--tls] <portnumber> -- [other_blobserver_opts]";
}

my $opt_wipe;
my $opt_tls;
my $opt_nobuild;
my $opt_all;  # listen on all interfaces

# keep indexes in memory only. often used with --wipe, but not
# necessarily. if --wipe isn't used, all blobs are re-indexed
# on start-up.
my $opt_memory;
my $opt_mongo;
GetOptions("wipe" => \$opt_wipe,
           "tls" => \$opt_tls,
           "all" => \$opt_all,
           "nobuild" => \$opt_nobuild,
           "memory" => \$opt_memory,
           "mongo" => \$opt_mongo,
    )
    or usage();

my $port = shift;
$port = "3179" unless defined($port);
usage() unless $port =~ /^\d+$/;

unless ($opt_nobuild) {
    system("./build.pl", "server/go/camlistored") and die "Failed to build camlistored";
    system("./build.pl", "clients/go/camdbinit") and die "Failed to build camdbinit";
}

my $root = "/tmp/camliroot-$ENV{USER}/port$port/";
if ($opt_wipe && -d $root) {
    print "Wiping $root\n";
    system("rm", "-rf", $root) and die "Failed to wipe $root.\n";
}

my $suffixdir = sub {
    my $suffix = shift;
    my $root = "$root/$suffix";
    unless (-d $root) {
        system("mkdir", "-p", $root) and die "Failed to create $root.\n";
    }
    return $root;
};

my $DBNAME = "devcamli$ENV{USER}";
my @opts;
if ($opt_wipe) {
    push @opts, "-wipe";
} else {
    push @opts, "-ignoreexists";
}

$ENV{"CAMLI_MYSQL_ENABLED"} = "false";
$ENV{"CAMLI_MONGO_ENABLED"} = "false";
if ($opt_memory) {
    $ENV{"CAMLI_INDEXER_PATH"} = "/index-mem/";
} else {
    if ($opt_mongo) {
        $ENV{"CAMLI_MONGO_ENABLED"} = "true";
        $ENV{"CAMLI_INDEXER_PATH"} = "/index-mongo/";
        # TODO(mpl): is this too hackish?
        if ($opt_wipe) {
            $ENV{"CAMLI_MONGO_WIPE"} = "true";
        } else {
            $ENV{"CAMLI_MONGO_WIPE"} = "false";
        }
    } else {
        $ENV{"CAMLI_MYSQL_ENABLED"} = "true";
        $ENV{"CAMLI_INDEXER_PATH"} = "/index-mysql/";
        system("./clients/go/camdbinit/camdbinit",
               "-user=root",
               "-password=root",
               "-host=localhost",
               "-database=$DBNAME",
               @opts) and die "Failed to run camdbinit.\n";
    }
}

my $base = "http://localhost:$port";
my $listen = "127.0.0.1:$port";
if ($opt_all) {
    $listen = "0.0.0.0:$port";
    my $host = `hostname`;
    chomp $host;
    $base = "http://$host:$port";
}
if ($opt_tls) {
    $base =~ s/^http/https/;
}

print "Starting dev server on $base/ui/ with password \"pass$port\"\n";

$ENV{CAMLI_TLS} = "false";
if ($opt_tls) {
    $ENV{CAMLI_TLS} = "true";
}
$ENV{CAMLI_BASEURL} = $base;
$ENV{CAMLI_AUTH} = "userpass:camlistore:pass$port";
$ENV{CAMLI_ADVERTISED_PASSWORD} = "pass$port"; # public password
$ENV{CAMLI_ROOT} = $suffixdir->("bs");
$ENV{CAMLI_ROOT_SHARD1} = $suffixdir->("s1");
$ENV{CAMLI_ROOT_SHARD2} = $suffixdir->("s2");
$ENV{CAMLI_ROOT_REPLICA1} = $suffixdir->("r1");
$ENV{CAMLI_ROOT_REPLICA2} = $suffixdir->("r2");
$ENV{CAMLI_ROOT_REPLICA3} = $suffixdir->("r3");
$ENV{CAMLI_ROOT_CACHE} = $suffixdir->("cache");
$ENV{CAMLI_PORT} = $port;
$ENV{CAMLI_SECRET_RING} = "$Bin/lib/go/camli/jsonsign/testdata/test-secring.gpg";
$ENV{CAMLI_DBNAME} = $DBNAME;

# To use resources from disk, instead of the copies linked into the
# binary:
$ENV{CAMLI_DEV_UI_FILES} = "$FindBin::Bin/server/go/camlistored/ui"; # set in server/go/camlistored/ui/fileembed.go

exec("$FindBin::Bin/server/go/camlistored/camlistored",
     "-configfile=$Bin/config/dev-server-config.json",
     "-listen=$listen",
     @ARGV);