/**
 * @license
 * Copyright 2020 The FOAM Authors. All Rights Reserved.
 *     http://www.apache.org/licenses/LICENSE-2.0
 */

package foam.nanos.mrac;

import foam.core.X;
import foam.core.ClassInfo;
import foam.core.FObject;
import foam.dao.java.JDAO;
import foam.dao.MDAO;
import foam.nanos.boot.NSpec;
import foam.core.Identifiable;
import foam.nanos.fs.ResourceStorage;
import foam.nanos.fs.Storage;
import foam.dao.AbstractSink;
import foam.core.Detachable;

public class MMDAO extends JDAO {

  String mnPort;
  //TODO: inject NSpec to record where the entry come from.
  //nSpec.getName();
  NSpec nspec;
  String nspecKey;

  //public MMDAO(X x, ClassInfo classInfo, String mnPort) {
  //  setX(x);
  //  setOf(classInfo);

  //  nspecKey = classInfo.getId();
  //  setDelegate(new MDAO(classInfo));
  //  setJournal(MMJournal.getMMjournal(x, mnPort));
  //  this.mnPort = mnPort;
  //  //TODO: command replay for testing election.
  //  // getJournal().replay(x, getDelegate());
  //}

  public MMDAO(X x, String nspecKey, MDAO dao, String mnPort, String fileName) {
    setX(x);
    setOf(dao.getOf());

    // Load journal from resource.journals first.
    X resourceStorageX = x;
    if ( System.getProperty("resource.journals.dir") != null ) {
      resourceStorageX = x.put(Storage.class,
          new ResourceStorage(System.getProperty("resource.journals.dir")));
    }
    new foam.dao.FileJournal.Builder(resourceStorageX)
      .setFilename(fileName+".0").build().replay(x, dao);

    System.out.println(">>>>>>>>nspecKey: " + nspecKey);
    dao.select(new AbstractSink() {
              public void put(Object obj, Detachable sub) {
                System.out.println(obj);
              }});

    this.nspecKey = nspecKey;
    setDelegate(dao);
    this.mnPort = mnPort;
    setJournal(MMJournal.getMMjournal(x, mnPort));
    ((MMJournal) getJournal()).replay(x, nspecKey, getDelegate());
  }
  //Remove synchronized key word.
  //TODO: move lock to here
  @Override
  public FObject put_(X x, FObject obj) {
    System.out.println("put>>>>>>>>>><<<<<<<<");
    if ( obj == null ) throw new RuntimeException("obj is null");

    Object id = ((Identifiable) obj).getPrimaryKey();
    String className = obj.getClass().getName();
    String uniqueString = className + id.toString();
    String uniqueStringLock = String.valueOf(uniqueString).intern();

    FObject result = null;
    //TODO: Change to assembly version.
    synchronized ( uniqueStringLock ) {
      getJournal().put(x, nspecKey, getDelegate(), obj);
      result = getDelegate().put_(x, obj);
    }
    return result;
  }

  //Remove synchronized key word.
  @Override
  public FObject remove_(X x, FObject obj) {
    System.out.println("remove>>>>>>>>>>><<<<<<<");
    if ( obj == null ) throw new RuntimeException("obj is null");

    Object id = ((Identifiable) obj).getPrimaryKey();
    String className = obj.getClass().getName();
    String uniqueString = className + id.toString();
    String uniqueStringLock = String.valueOf(uniqueString).intern();

    FObject result = null;
    synchronized ( uniqueStringLock ) {
      result = getDelegate().find_(x, obj.getProperty("id"));
      if ( result == null ) throw new RuntimeException("Record do not find. Id: " + obj.getProperty("id"));
      getJournal().remove(x, nspecKey, getDelegate(), obj);
      result = getDelegate().remove_(x, obj);
    }
    return result;
  }

}

@@ -1499,222 +1499,8 @@
 );%0A%0A
-    System.out.println(%22%3E%3E%3E%3E%3E%3E%3E%3EnspecKey: %22 + nspecKey);%0A    dao.select(new AbstractSink() %7B%0A              public void put(Object obj, Detachable sub) %7B%0A                System.out.println(obj);%0A              %7D%7D);%0A%0A
     
@@ -1525,16 +1525,16 @@
 pecKey;%0A
+
     setD
@@ -1815,57 +1815,8 @@
 ) %7B%0A
-    System.out.println(%22put%3E%3E%3E%3E%3E%3E%3E%3E%3E%3E%3C%3C%3C%3C%3C%3C%3C%3C%22);%0A
     
@@ -2379,32 +2379,32 @@
 rd.%0A  @Override%0A
+
   public FObject
@@ -2436,60 +2436,8 @@
 ) %7B%0A
-    System.out.println(%22remove%3E%3E%3E%3E%3E%3E%3E%3E%3E%3E%3E%3C%3C%3C%3C%3C%3C%3C%22);%0A
     

format code on MMDAO.java