let fs = require('fs');

fcf.module({
  name: "fcf:tests/NFSQL/DB.FieldFileRefJoin.js",
  dependencies: ["fcf:NTest/uniTest.js", "fcf:tests/NFSQL/Helpers/Helper.js"],
  module: function(uniTest, Helper) {
    uniTest.add("FSQL DB" , "DB Field File (Ref 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_refjoin" }, (a_records) => {
      });

      Helper.query(a_tester, { query: "INSERT INTO fcftest_file_table_refjoin (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_refjoin 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_refjoin 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_refjoin 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_refjoin (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_refjoin 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_refjoin 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_refjoin 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_refjoin (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_refjoin 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_refjoin 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_refjoin", 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_refjoin" });
      });

      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_refjoin (file1) VALUES (${1}); INSERT INTO fcftest_file_table_refjoin (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_refjoin 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_refjoin 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_refjoin 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_refjoin 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_refjoin 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_refjoin", });
      });

      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_refjoin (file1) VALUES (${1}); INSERT INTO fcftest_file_table_refjoin (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_refjoin 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_refjoin 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_refjoin 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_refjoin 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_refjoin" });
      });


      // Checking Where
      //------------------------------------------------------------------------
      a_tester.actions.then(() => {
        return Helper.query(a_tester, 
                            { 
                              actions: fcf.actions(), 
                              query: "INSERT INTO fcftest_file_table_refjoin (file1) VALUES (${1});" + 
                                     "INSERT INTO fcftest_file_table_refjoin (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_refjoin WHERE index = ${1};" + 
                   "SELECT index, file1 FROM fcftest_file_table_refjoin 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_refjoin 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_refjoin 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_refjoin" });
      });

    });
  }
});
