package com.orientechnologies.orient.server.tx;

import com.orientechnologies.orient.core.Orient;
import com.orientechnologies.orient.core.db.ODatabaseType;
import com.orientechnologies.orient.core.db.OrientDB;
import com.orientechnologies.orient.core.db.OrientDBConfig;
import com.orientechnologies.orient.core.db.document.ODatabaseDocument;
import com.orientechnologies.orient.core.db.record.OIdentifiable;
import com.orientechnologies.orient.core.record.impl.ODocument;
import com.orientechnologies.orient.core.sql.executor.OResultSet;
import com.orientechnologies.orient.server.OServer;
import com.orientechnologies.orient.server.network.ORemoteImportTest;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import static org.junit.Assert.*;

/**
 * Created by tglman on 03/01/17.
 */
public class RemoteTransactionSupportTest {

  private static final String SERVER_DIRECTORY = "./target/transaction";
  private OServer           server;
  private OrientDB          orientDB;
  private ODatabaseDocument database;

  @Before
  public void before() throws Exception {
    server = new OServer();
    server.setServerRootDirectory(SERVER_DIRECTORY);
    server.startup(getClass().getResourceAsStream("orientdb-server-config.xml"));
    server.activate();

    orientDB = new OrientDB("remote:localhost", "root", "root", OrientDBConfig.defaultConfig());
    orientDB.create(ORemoteImportTest.class.getSimpleName(), ODatabaseType.MEMORY);
    database = orientDB.open(ORemoteImportTest.class.getSimpleName(), "admin", "admin");
    database.createClass("SomeTx");
    database.createClass("SomeTx2");
  }

  @Test
  public void testQueryUpdateUpdatedInTxTransaction() {
    ODocument doc = new ODocument("SomeTx");
    doc.setProperty("name", "Joe");
    OIdentifiable id = database.save(doc);
    database.begin();
    ODocument doc2 = database.load(id.getIdentity());
    doc2.setProperty("name", "Jane");
    database.save(doc2);
    OResultSet result = database.command("update SomeTx set name='July' where name = 'Jane' ");
    assertEquals((long) result.next().getProperty("count"), 1L);
    ODocument doc3 = database.load(id.getIdentity());
    assertEquals(doc3.getProperty("name"), "July");
  }

  @Test
  public void testQueryUpdateCreatedInTxTransaction() {
    database.begin();
    ODocument doc1 = new ODocument("SomeTx");
    doc1.setProperty("name", "Jane");
    OIdentifiable id = database.save(doc1);

    ODocument docx = new ODocument("SomeTx2");
    docx.setProperty("name", "Jane");
    database.save(docx);

    OResultSet result = database.command("update SomeTx set name='July' where name = 'Jane' ");
    assertTrue(result.hasNext());
    assertEquals((long) result.next().getProperty("count"), 1L);
    ODocument doc2 = database.load(id.getIdentity());
    assertEquals(doc2.getProperty("name"), "July");
    assertFalse(result.hasNext());
  }

  @Test
  public void testRollbackTxTransaction() {
    ODocument doc = new ODocument("SomeTx");
    doc.setProperty("name", "Jane");
    database.save(doc);

    database.begin();
    ODocument doc1 = new ODocument("SomeTx");
    doc1.setProperty("name", "Jane");
    database.save(doc1);

    OResultSet result = database.command("update SomeTx set name='July' where name = 'Jane' ");
    assertTrue(result.hasNext());
    assertEquals((long) result.next().getProperty("count"), 2L);

    database.rollback();

    OResultSet result1 = database.command("select count(*) from SomeTx where name='Jane'");
    assertTrue(result1.hasNext());
    assertEquals((long) result1.next().getProperty("count(*)"), 1L);

  }

  @Test
  public void testRollbackTxChekcStatusTransaction() {
    ODocument doc = new ODocument("SomeTx");
    doc.setProperty("name", "Jane");
    database.save(doc);

    database.begin();
    ODocument doc1 = new ODocument("SomeTx");
    doc1.setProperty("name", "Jane");
    database.save(doc1);

    OResultSet result = database.command("select count(*) from SomeTx where name='Jane' ");
    assertTrue(result.hasNext());
    assertEquals((long) result.next().getProperty("count(*)"), 2L);

    assertTrue(database.getTransaction().isActive());

    database.rollback();

    OResultSet result1 = database.command("select count(*) from SomeTx where name='Jane'");
    assertTrue(result1.hasNext());
    assertEquals((long) result1.next().getProperty("count(*)"), 1L);

    assertFalse(database.getTransaction().isActive());

  }

  @After
  public void after() {
    database.close();
    orientDB.close();
    server.shutdown();
    Orient.instance().startup();
  }

}

@@ -946,24 +946,26 @@
 r           
+  
 server;%0A  pr
@@ -984,24 +984,26 @@
 DB          
+  
 orientDB;%0A  
@@ -1028,16 +1028,18 @@
 ocument 
+  
 database
@@ -4445,16 +4445,582 @@
 ;%0A%0A  %7D%0A%0A
+  @Test%0A  public void testQueryUpdateCreatedInTxSQLTransaction() %7B%0A    database.begin();%0A%0A    database.command(%22insert into SomeTx set name ='Jane' %22);%0A%0A    OResultSet result = database.command(%22update SomeTx set name='July' where name = 'Jane' %22);%0A    assertTrue(result.hasNext());%0A    assertEquals((long) result.next().getProperty(%22count%22), 1L);%0A    OResultSet result1 = database.query(%22select from SomeTx where name='July'%22);%0A    assertTrue(result1.hasNext());%0A    assertEquals(result1.next().getProperty(%22name%22), %22July%22);%0A    assertFalse(result.hasNext());%0A  %7D%0A%0A
   @After

add full sql test case for transactions