package com.orientechnologies.orient.server.network.http;

import com.orientechnologies.orient.core.record.impl.ODocument;
import org.apache.http.HttpResponse;
import org.apache.http.util.EntityUtils;
import org.testng.Assert;
import org.testng.annotations.Test;

import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;
import java.util.List;

/**
 * Test HTTP "batch" command.
 * 
 * @author Luca Garulli (l.garulli--at-orientechnologies.com)
 */
@Test
public class HttpBatchTest extends BaseHttpDatabaseTest {
  public void batchUpdate() throws IOException {
    Assert.assertEquals(post("command/" + getDatabaseName() + "/sql/").payload("create class User", CONTENT.TEXT).getResponse()
        .getStatusLine().getStatusCode(), 200);

    Assert.assertEquals(
        post("command/" + getDatabaseName() + "/sql/").payload("insert into User content {\"userID\": \"35862601\"}", CONTENT.TEXT)
            .setUserName("admin").setUserPassword("admin").getResponse().getStatusLine().getStatusCode(), 200);

    String response = EntityUtils.toString(getResponse().getEntity());

    Assert.assertNotNull(response);

    ODocument insertedDocument = ((List<ODocument>) new ODocument().fromJSON(response).field("result")).get(0);

    // TEST UPDATE
    Assert.assertEquals(
        post("batch/" + getDatabaseName() + "/sql/")
            .payload(
                "{\n" + "    \"transaction\": true,\n" + "    \"operations\": [{\n" + "        \"record\": {\n"
                    + "            \"userID\": \"35862601\",\n" + "            \"externalID\": \"35862601\",\n"
                    + "            \"@rid\": \"" + insertedDocument.getIdentity() + "\", \"@class\": \"User\", \"@version\": "
                    + insertedDocument.getVersion() + "\n" + "        },\n" + "        \"type\": \"u\"\n" + "    }]\n" + "}",
                CONTENT.JSON).getResponse().getStatusLine().getStatusCode(), 200);

    // TEST DOUBLE UPDATE
    Assert.assertEquals(
        post("batch/" + getDatabaseName() + "/sql/")
            .payload(
                "{\n" + "    \"transaction\": true,\n" + "    \"operations\": [{\n" + "        \"record\": {\n"
                    + "            \"userID\": \"35862601\",\n" + "            \"externalID\": \"35862601\",\n"
                    + "            \"@rid\": \"" + insertedDocument.getIdentity() + "\", \"@class\": \"User\", \"@version\": "
                    + (insertedDocument.getVersion() + 1) + "\n" + "        },\n" + "        \"type\": \"u\"\n" + "    }]\n" + "}",
                CONTENT.JSON).getResponse().getStatusLine().getStatusCode(), 200);

    // TEST WRONG VERSION ON UPDATE
    Assert.assertEquals(
        post("batch/" + getDatabaseName() + "/sql/")
            .payload(
                "{\n" + "    \"transaction\": true,\n" + "    \"operations\": [{\n" + "        \"record\": {\n"
                    + "            \"userID\": \"35862601\",\n" + "            \"externalID\": \"35862601\",\n"
                    + "            \"@rid\": \"" + insertedDocument.getIdentity() + "\", \"@class\": \"User\", \"@version\": "
                    + (insertedDocument.getVersion() + 1) + "\n" + "        },\n" + "        \"type\": \"u\"\n" + "    }]\n" + "}",
                CONTENT.JSON).getResponse().getStatusLine().getStatusCode(), 409);

    batchWithEmpty();
  }

  private void batchWithEmpty() throws IOException {
    String json = "{\n"
        + "\"operations\": [{\n"
        + "\"type\": \"script\",\n"
        + "\"language\": \"SQL\","
        + "\"script\": \"let $a = select from User limit 2 \\n"
        + "let $b = select sum(foo) from (select from User where name = foo) \\n"
        + "return [$a, $b]\""
        + "}]\n"
        + "}";
    System.out.println(json);
    HttpResponse response = post("batch/" + getDatabaseName() ).payload(
            json,
        CONTENT.TEXT).getResponse();

    Assert.assertEquals(response.getStatusLine().getStatusCode(), 200);
    InputStream stream = response.getEntity().getContent();
    ODocument doc = new ODocument();
    doc.fromJSON(stream);
    stream.close();
    Iterable iterable = doc.field("result");

    Iterator iterator = iterable.iterator();
    Assert.assertTrue(iterator.hasNext());
    iterator.next();
    Assert.assertTrue(iterator.hasNext());
    Object emptyList = iterator.next();
    Assert.assertNotNull(emptyList);
    Assert.assertTrue(emptyList instanceof Iterable);
    Iterator emptyListIterator = ((Iterable) emptyList).iterator();
    Assert.assertFalse(emptyListIterator.hasNext());
  }
    @Override
  public String getDatabaseName() {
    return "httpscript";
  }
}

@@ -257,16 +257,47 @@
 .Test;%0A%0A
+import java.io.BufferedReader;%0A
 import j
@@ -344,16 +344,50 @@
 Stream;%0A
+import java.io.InputStreamReader;%0A
 import j
@@ -3735,19 +3735,26 @@
  name = 
+'adsfa
 foo
+'
 ) %5C%5Cn%22%0A 
@@ -3818,38 +3818,8 @@
 %7D%22;%0A
-    System.out.println(json);%0A
     
@@ -4071,24 +4071,277 @@
 tContent();%0A
+    String string = %22%22;%0A    BufferedReader reader = new BufferedReader(new InputStreamReader(stream));%0A    String line = reader.readLine();%0A    while(line!=null)%7B%0A      string+=line;%0A      line = reader.readLine();%0A    %7D%0A    System.out.println(string);%0A
     ODocumen
@@ -4389,14 +4389,15 @@
 (str
-eam
+ing
 );%0A
+%0A
     
@@ -4440,29 +4440,78 @@
 e = 
-doc.field(%22result%22);%0A
+(Iterable)doc.eval(%22result.value%22);%0A%0A    System.out.println(iterable);
 %0A   

Fix test case on HTTP