#!/usr/bin/perl -X
use Cwd;
use strict;
use warnings;
use Config::Auto;


my %conf = ( );
GetOptions( \%conf, "whitespace|ws!", "version","structures", "help", "remote","new",
                    "init", "export", "import",
                    "check", "category=s", "sources" ,"drop");

our ($new, $write,$drop,$all) =(0,0,0,0);
my @CWD; push @CWD, getcwd();
our $structdir = "structures";
our $absstructdir = "$CWD[0]/$structdir";


if( grep{/\ball\b/} @ARGV ){ $all = 1; cleanArgs("all");  };


use AI::MicroStructure;
use Getopt::Long;
use Data::Dumper;
use JSON::XS;
our $main = AI::MicroStructure->new();
my $usage = << 'EOT';

  #current status
  #did you create a micro structure yet ?
  #try something like this

  $ micro new ufo;      # creates a structure called ufo

  $ micro drop ufo;     # deletes the structure called ufo

  $ micro structures;   # shows all structure's you currently have

  #after creation of a structure you can access it in lots of ways



  $ micro;             # one word of a random structure

  $ micro ufo;         # one word of the ufo structure

  $ micro ufo all;     # all words of the ufo structure

  $ micro ufo 5;       # 5 random words of the ufo structure

  $ micro any 10;      # 10 random words of any structure you have created


  $ micro --init        # initializes active memory

  $ micro --export      # export relations from couchdb into git repo and tag data


  # oneliners i like to use

  $  for i in `micro structures`; do echo $i; done;       # echos all the structures

  $  for i in `micro ufo all`;   do echo $i; done;       # echos all words in ufo

  $  for i in `micro structures`; do micro all $i; done;  # echos all stuctures all words

  $  for i in `micro ufo all`;   do micro new $i; done;  # new structure for all words in ufo

  $  for i in `micro ufo all`;   do micro-wiki $i; done; # push all words against the wiki plugin dont forget setting user & password in /usr/local/bin/micro-wiki

  ###################################################################################
  # try to follow the logic combine
  # your-word=micro new ? ->concept->concepts->relations->node


  $ micro new biology
  $ micro new biological_process

  $ for i in `micro structures`; do
  $ for y in `micro all $i `; do
  $ echo "$i=$y";
  $ micro new $y;
  $ done
  $ done

  #!!!!!###Hard cpu to expect ### make sure couch is on   ######  or disable the store methode in micro-wiki and print $doc or consume otherweise
  # test as single before you loope 
  
  $ micro-wiki ufo
  
  # proceed

  $ for i in `micro structures`; do
  $ for y in `micro all $i `; do
  $ echo "$i=$y";
  $ micro-wiki $y;
  $ done
  $ done


EOT


if($conf{"help"}) {

    printf($usage);
    exit(0);

}


# check if this is an active memory or initialize it
if($conf{"init"}) {
    if (-e  ".micro") {
        print STDERR "this is already an active memory!\n";
    } else {
        print `git init && touch .micro && echo .pmc > .gitignore && echo '*~' >> .gitignore && echo '*swp' >> .gitignore && echo .micro >> .gitignore && git add -f .micro .gitignore && git commit -m 'active memory born'`;
    }
    exit;
} else {
    if (!-e ".micro") {
        print STDERR "this directory is not an active memory!\n";
        exit;
    }
}

my $config = Config::Auto::parse(".micro", path => @CWD);
$config->{couchdb} ||= "http://user::pass\@localhost:5984/";
$config->{db}      ||= "micro-relations";

if ($conf{"export"}) {
    my $hash =  $main->fitnes($config); # FIXME
    my $url = sprintf("%s/%s/_all_docs", $config->{couchdb}, $config->{db});
    print `mkdir -p relations && wget -O relations/any.json $url && git add relations/any.json $structdir/*.pm && git commit -m 'active memory release' && git tag $hash`; # FIXME check for errors FIXME also that we commit per structure and/or per relation

    exit;
}

my (@remote, @local);
# real processing starts here
$\ = $/;
my $sep = $conf{whitespace} ? ' ' : $\;

my $j = $main->structures();


if($j == 0 || $j eq "any"){

print $usage;
exit;
}



sub cleanArgs{
    my ($key) = @_;
    my @tmp=();
    foreach(@ARGV){
    push @tmp,$_ unless($_=~/$key/);}

    @ARGV=@tmp;
}



my $structure;

if(defined($ARGV[0]) && $ARGV[0] =~ m/structures/){

    @local = grep{!/any/}AI::MicroStructure->new()->structures();

    print join $sep, @local, @remote;
    exit;
}

if($conf{"new"} and $ARGV[0] !~/structures/  and $ARGV[0] =~ m{^([^/]+)/(.*)}s) {
    $structure          = $1;
    $conf{category} = $2;

    my $meta = AI::MicroStructure->new( $structure, category => "new" );
    exit;
}



if(!$conf{"drop"} && !$conf{"write"}and $ARGV[0] !~/structures/){



# find out the structure name
$structure = shift || $AI::MicroStructure::structure;

if (!length $conf{category} && $structure =~ m{^([^/]+)/(.*)}s) {
    $structure          = $1;
    $conf{category} = $2;
}


AI::MicroStructure->new( $structure, category => "new" )
 unless AI::MicroStructure->has_structure( $structure );

# my $module = "AI::MicroStructure::$structure";
my $module = "$absstructdir/$structure.pm";


# load the remote structure if needed
if ( $conf{remote} || $conf{check} || $conf{sources}) {
    eval "require '$module';";
    die "structure '$structure' is not updatable!\n"
        unless $module->has_remotelist();
}

# informative options
print STDERR
"meta, a simple front-end to AI::MicroStructure version $AI::MicroStructure::VERSION\n"
  if $conf{version};
print STDERR $usage if $conf{help};
print map "$_\n", AI::MicroStructure->structures if $conf{structures};
if ( $conf{sources} ) {
    my @sources = $module->sources( $conf{category} );
    print map "$_\n", @sources;
}
exit if $conf{structures} || $conf{version} || $conf{help} || $conf{sources};


my $meta = AI::MicroStructure->new( $structure, category => $conf{category} );

@remote = $module->remote_list( $conf{category} )
    if $conf{remote} || $conf{check};
if ( !$conf{remote} ) {
    my $count = shift;
    $count = 1 unless defined $count;
    $count = 0 if $conf{check};
    if($all){
    @local = $meta->name(0,scalar "");
    }else{
    @local = $meta->name($count);
    }
}
if ( $conf{check} ) {
    my %seen;
    $seen{$_}++ for @remote;
    $seen{$_}-- for @local;
    foreach my $key ( sort keys %seen ) {
        next unless $seen{$key};
        print $seen{$key} > 0 ? "+ $key" : "- $key";
    }
}
else {
    print join $sep, @local, @remote;
}

}

END{
#    print Dumper  [$structure,@ARGV,%conf];
}


