let fs = require('fs');

fcf.module({
  name: "fcf:tests/NFSQL/DB.FieldFileJoin.js",
  dependencies: ["fcf:NTest/uniTest.js", "fcf:tests/NFSQL/Helpers/Helper.js"],
  module: function(uniTest, Helper) {
    uniTest.add("FSQL DB" , "DB Field File (Join)", function(a_tester) {
      let lastKey = undefined;
      let lastKey1 = undefined;
      let lastKey2 = undefined;
      let oldFilePath = undefined;
      let newFilePath = undefined;
      let oldFilePath1 = undefined;
      let newFilePath1 = undefined;
      let oldFilePath2 = undefined;
      let newFilePath2 = undefined;

      a_tester.actions.then((a_res, a_act) => {
        fs.writeFileSync('testfile1.txt', '1');
        fs.writeFileSync('testfile2.txt', '2');
        fs.writeFileSync('testfile3.txt', '3');
        a_act.complete();
      });


      // Checking Creation and Deletion (Short)
      //------------------------------------------------------------------------

      Helper.query(a_tester, { query: "DELETE FROM fcftest_file_table_join" }, (a_records) => {
      });

      Helper.query(a_tester, { query: "INSERT INTO fcftest_file_table_join (file1) VALUES (${1})", args: ["testfile1.txt"]}, (a_records) => {
        lastKey = fcf.first2(a_records)["@key"];
      });

      a_tester.actions.then(() => {
        return Helper.query(a_tester, { actions: fcf.actions(), query: "SELECT index, file1 FROM fcftest_file_table_join WHERE index = ${1}", args: [lastKey]}, (a_records) => {
          uniTest.equal(a_records[0].length, 1);
          uniTest.equal(a_records[0][0].file1.alias, "testfile1.txt");
          newFilePath = a_records[0][0].file1.file;
          uniTest.equal(fs.existsSync(fcf.getPath(newFilePath)), true);
        });
      });

      a_tester.actions.then(() => {
        return Helper.query(a_tester, { actions: fcf.actions(), query: "SELECT file1->alias FROM fcftest_file_table_join WHERE index = ${1}", args: [lastKey]}, (a_records) => {
          delete a_records[0][0]["@key"];
          uniTest.equal(a_records, [ [ { "file1->alias": "testfile1.txt" } ] ]);
        });
      });

      a_tester.actions.then(() => {
        return Helper.query(a_tester, { actions: fcf.actions(), query: "DELETE FROM fcftest_file_table_join WHERE index = ${1}", args: [lastKey]}, (a_records) => {
          uniTest.equal(fs.existsSync(fcf.getPath(newFilePath)), false);
        });
      });


      // Checking Creation and Deletion (Full)
      //------------------------------------------------------------------------

      a_tester.actions.then(() => {
        return Helper.query(a_tester, { actions: fcf.actions(), query: "INSERT INTO fcftest_file_table_join (file1) VALUES (${1})", args: [{file: "testfile1.txt", alias: "file"}]}, (a_records) => {
          lastKey = fcf.first2(a_records)["@key"];
        });
        a_act.complete();
      });


      a_tester.actions.then(() => {
        return Helper.query(a_tester, { actions: fcf.actions(), query: "SELECT index, file1 FROM fcftest_file_table_join WHERE index = ${1}", args: [lastKey]}, (a_records) => {
          uniTest.equal(a_records[0].length, 1);
          uniTest.equal(a_records[0][0].file1.alias, "file");
          newFilePath = a_records[0][0].file1.file;
          uniTest.equal(fs.existsSync(fcf.getPath(newFilePath)), true);
        });
        a_act.complete();
      });

      a_tester.actions.then(() => {
        return Helper.query(a_tester, { actions: fcf.actions(), query: "SELECT file1->alias FROM fcftest_file_table_join WHERE index = ${1}", args: [lastKey]}, (a_records) => {
          delete a_records[0][0]["@key"];
          uniTest.equal(a_records, [ [ { "file1->alias": "file" } ] ]);
        });
        a_act.complete();
      });

      a_tester.actions.then(() => {
        return Helper.query(a_tester, { actions: fcf.actions(), query: "DELETE FROM fcftest_file_table_join WHERE index = ${1}", args: [lastKey]}, (a_records) => {
          uniTest.equal(fs.existsSync(fcf.getPath(newFilePath)), false);
        });
        a_act.complete();
      });


      // Checking Updation (Full Single)
      //------------------------------------------------------------------------
      a_tester.actions.then(() => {
        return Helper.query(a_tester, { actions: fcf.actions(), query: "INSERT INTO fcftest_file_table_join (file1) VALUES (${1})", args: ["testfile1.txt"]}, (a_records) => {
          lastKey = fcf.first2(a_records)["@key"];
        });
      });

      a_tester.actions.then(() => {
        return Helper.query(a_tester, { actions: fcf.actions(), query: "SELECT index, file1 FROM fcftest_file_table_join WHERE index = ${1}", args: [lastKey]}, (a_records) => {
          oldFilePath = a_records[0][0].file1.file;
        });
      });

      a_tester.actions.then(() => {
        return Helper.query(a_tester, { actions: fcf.actions(), query: "UPDATE fcftest_file_table_join SET file1 = ${1} WHERE index = ${2}", args: [{file: "testfile2.txt"}, lastKey]}, (a_records) => {
        });
      });

      a_tester.actions.then(() => {
        return Helper.query(a_tester, { actions: fcf.actions(), query: "SELECT index, file1 FROM fcftest_file_table_join", args: []}, (a_records) => {
          newFilePath = a_records[0][0].file1.file;
          uniTest.notEqual(newFilePath, oldFilePath);
          let fileData = fs.readFileSync(fcf.getPath(newFilePath), 'utf8');
          uniTest.equal(fileData, "2");
        });
      });

      a_tester.actions.then(() => {
        return Helper.query(a_tester, { actions: fcf.actions(), query: "DELETE FROM fcftest_file_table_join" });
      });

      a_tester.actions.then(() => {
        uniTest.equal(fs.existsSync(fcf.getPath(newFilePath)), false);
      });



      // Checking Updation (Full Multi)
      //------------------------------------------------------------------------
      a_tester.actions.then(() => {
        return Helper.query(a_tester, { actions: fcf.actions(), query: "INSERT INTO fcftest_file_table_join (file1) VALUES (${1}); INSERT INTO fcftest_file_table_join (file1) VALUES (${2});",
                                 args:  ["testfile1.txt", "testfile2.txt"]},
                                 (a_records) => {
                                   lastKey1 = a_records[0][0]["@key"];
                                   lastKey2 = a_records[1][0]["@key"];
                                });
      });

      a_tester.actions.then(() => {
        return Helper.query(a_tester, { actions: fcf.actions(), query: "SELECT index, file1 FROM fcftest_file_table_join WHERE index = ${1}", args: [lastKey1]}, (a_records) => {
          oldFilePath1 = a_records[0][0].file1.file;
          let fileData = fs.readFileSync(fcf.getPath(oldFilePath1), 'utf8');
          uniTest.equal(fileData, "1");
        });
      });

      a_tester.actions.then(() => {
        return Helper.query(a_tester, { actions: fcf.actions(), query: "SELECT index, file1 FROM fcftest_file_table_join WHERE index = ${1}", args: [lastKey2]}, (a_records) => {
          oldFilePath2 = a_records[0][0].file1.file;
          let fileData = fs.readFileSync(fcf.getPath(oldFilePath2), 'utf8');
          uniTest.equal(fileData, "2");
        });
      });

      a_tester.actions.then(() => {
        return Helper.query(a_tester, { actions: fcf.actions(), query: "UPDATE fcftest_file_table_join SET file1 = ${1}", args: [{file: "testfile3.txt", alias: "testfileX.txt"} ]}, (a_records) => {
        });
      });

      a_tester.actions.then(() => {
        return Helper.query(a_tester, { actions: fcf.actions(), query: "SELECT index, file1 FROM fcftest_file_table_join WHERE index = ${1}", args: [lastKey1]}, (a_records) => {
          newFilePath1 = a_records[0][0].file1.file;
          uniTest.equal(a_records[0][0].file1.alias, "testfileX.txt");
          let fileData = fs.readFileSync(fcf.getPath(newFilePath1), 'utf8');
          uniTest.equal(fileData, "3");
        });
      });

      a_tester.actions.then(() => {
        return Helper.query(a_tester, { actions: fcf.actions(), query: "SELECT index, file1 FROM fcftest_file_table_join WHERE index = ${1}", args: [lastKey2]}, (a_records) => {
          newFilePath2 = a_records[0][0].file1.file;
          uniTest.equal(a_records[0][0].file1.alias, "testfileX.txt");
          let fileData = fs.readFileSync(fcf.getPath(newFilePath2), 'utf8');
          uniTest.equal(fileData, "3");
          uniTest.notEqual(newFilePath1, newFilePath2);
        });
      });

      a_tester.actions.then(() => {
        return Helper.query(a_tester, { actions: fcf.actions(), query: "DELETE FROM fcftest_file_table_join", });
      });

      a_tester.actions.then(() => {
        uniTest.equal(fs.existsSync(fcf.getPath(newFilePath1)), false);
        uniTest.equal(fs.existsSync(fcf.getPath(newFilePath2)), false);
      });



      // Checking Updation (Sort)
      //------------------------------------------------------------------------
      a_tester.actions.then(() => {
        return Helper.query(a_tester, { actions: fcf.actions(), query: "INSERT INTO fcftest_file_table_join (file1) VALUES (${1}); INSERT INTO fcftest_file_table_join (file1) VALUES (${2});",
                                 args:  ["testfile1.txt", "testfile2.txt"]},
                                 (a_records) => {
                                   lastKey1 = a_records[0][0]["@key"];
                                   lastKey2 = a_records[1][0]["@key"];
                                });
      });

      a_tester.actions.then(() => {
        return Helper.query(a_tester, { actions: fcf.actions(), query: "UPDATE fcftest_file_table_join SET file1->file = ${1}, file1->alias = ${2}", args: ["testfile3.txt", "testfileX.txt"]}, (a_records) => {
        });
      });

      a_tester.actions.then(() => {
        return Helper.query(a_tester, { actions: fcf.actions(), query: "SELECT index, file1 FROM fcftest_file_table_join WHERE index = ${1}", args: [lastKey1]}, (a_records) => {
          newFilePath1 = a_records[0][0].file1.file;
          uniTest.equal(a_records[0][0].file1.alias, "testfileX.txt");
          let fileData = fs.readFileSync(fcf.getPath(newFilePath1), 'utf8');
          uniTest.equal(fileData, "3");
        });
      });

      a_tester.actions.then(() => {
        return Helper.query(a_tester, { actions: fcf.actions(), query: "UPDATE fcftest_file_table_join SET file1->alias = ${1} WHERE index = ${2}", args: ["testfileZ.txt", lastKey1]}, (a_records) => {
        });
      });

      a_tester.actions.then(() => {
        return Helper.query(a_tester, { actions: fcf.actions(), query: "SELECT index, file1 FROM fcftest_file_table_join WHERE index = ${1}", args: [lastKey1]}, (a_records) => {
          uniTest.equal(a_records[0][0].file1.file, newFilePath1);
          uniTest.equal(a_records[0][0].file1.alias, "testfileZ.txt");
          let fileData = fs.readFileSync(fcf.getPath(newFilePath1), 'utf8');
          uniTest.equal(fileData, "3");
        });
      });


      a_tester.actions.then(() => {
        return Helper.query(a_tester, { actions: fcf.actions(), query: "DELETE FROM fcftest_file_table_join" });
      });


      // // Checking Where
      // //------------------------------------------------------------------------
      a_tester.actions.then(() => {
        return Helper.query(a_tester, { actions: fcf.actions(), query: "INSERT INTO fcftest_file_table_join (file1) VALUES (${1}); INSERT INTO fcftest_file_table_join (file1) VALUES (${2});",
                                 args:  [{file: "testfile1.txt", alias: "testfileX1.txt"}, {file: "testfile2.txt", alias: "testfileX2.txt"}]},
                                 (a_records) => {
                                   lastKey1 = a_records[0][0]["@key"];
                                   lastKey2 = a_records[1][0]["@key"];
                                });
      });

      a_tester.actions.then(() => {
        return Helper.query(
          a_tester,
          { actions: fcf.actions(), query: "SELECT index, file1 FROM fcftest_file_table_join WHERE index = ${1}; SELECT index, file1 FROM fcftest_file_table_join WHERE index = ${2}",
            args: [lastKey1, lastKey2]}, (a_records) => {
              oldFilePath1 = a_records[0][0].file1.file;
              oldFilePath2 = a_records[1][0].file1.file;
          }
        );
      });

      a_tester.actions.then(() => {
        return Helper.query(a_tester, { actions: fcf.actions(), query: "SELECT index, file1 FROM fcftest_file_table_join WHERE file1->file = ${1};", args: [oldFilePath1]}, (a_records) => {
          uniTest.equal(a_records[0][0].file1.file, oldFilePath1);
          uniTest.equal(a_records[0][0].file1.alias, "testfileX1.txt");
        });
      });

      a_tester.actions.then(() => {
        return Helper.query(a_tester, { actions: fcf.actions(), query: "SELECT index, file1 FROM fcftest_file_table_join WHERE file1->alias = ${1};", args: ["testfileX2.txt"]}, (a_records) => {
          uniTest.equal(a_records[0][0].file1.file, oldFilePath2);
          uniTest.equal(a_records[0][0].file1.alias, "testfileX2.txt");
        });
      });

      a_tester.actions.then(() => {
        return Helper.query(a_tester, { actions: fcf.actions(), query: "DELETE FROM fcftest_file_table_join" });
      });

      a_tester.actions.then(() => {
        return Helper.query(a_tester, { actions: fcf.actions(), query: "SELECT file1 FROM fcftest_file_table_join", args: []}, (a_records) => {
          uniTest.equal(a_records[0].length, 0);
        });
      });

      a_tester.actions.then(() => {
        return Helper.query(a_tester, { actions: fcf.actions(), query: "SELECT file1 FROM fcftest_file_table", args: []}, (a_records) => {
          uniTest.equal(a_records[0].length, 0);
        });
      });

    });
  }
});
