"use strict";

var assert = require("assert");
var path = require("path");
var fs = require("fs");

var resolveUniversalApiWorkflow = function resolveUniversalApiWorkflow(
  provider,
  bucketName,
  filePath,
  filenameTxt
) {
  provider
    .createBucket(bucketName)
    .then(function(data) {
      console.log(data);
      assert.deepEqual(data, {
        status: 201,
        message: 'Bucket "' + bucketName + '" was created successfully'
      });

      provider
        .uploadFile(bucketName, filePath)
        .then(function(data) {
          console.log(data);
          assert.deepEqual(data, {
            status: 200,
            message:
              'File "' +
              filePath +
              '" was uploaded successfully to bucket "' +
              bucketName +
              '"'
          });

          var filename = path.basename(filePath);
          provider
            .downloadFile(bucketName, filename, "downloaded-binary.bin")
            .then(function(data) {
              console.log(data);
              assert.deepEqual(data, {
                status: 200,
                message:
                  'File "' +
                  filename +
                  '" was downloaded successfully from bucket "' +
                  bucketName +
                  '"'
              });

              var existsFile = fs.existsSync("downloaded-binary.bin");
              assert.equal(existsFile, true);

              // Delete downloaded file
              fs.unlinkSync("downloaded-binary.bin");

              var txt = "This is a random text \n Second Line";
              provider
                .createFileFromText(bucketName, filenameTxt, txt)
                .then(function(data) {
                  console.log(data);
                  assert.deepEqual(data, {
                    status: 200,
                    message:
                      'Object "' +
                      filenameTxt +
                      '" was saved successfully in bucket "' +
                      bucketName +
                      '"'
                  });

                  provider
                    .readFile(bucketName, filenameTxt)
                    .then(function(data) {
                      console.log(data);
                      assert.deepEqual(data, {
                        status: 200,
                        data: txt,
                        message:
                          'Object "' +
                          filenameTxt +
                          '" was fetched successfully from bucket "' +
                          bucketName +
                          '"'
                      });

                      provider
                        .getListOfFiles(bucketName)
                        .then(function(data) {
                          console.log(data);
                          assert.deepEqual(data, {
                            status: 200,
                            data: [
                              {
                                filename: filename
                              },
                              {
                                filename: filenameTxt
                              }
                            ],
                            message:
                              'The list of objects was fetched successfully from bucket "' +
                              bucketName +
                              '"'
                          });

                          provider
                            .deleteFile(bucketName, filename)
                            .then(function(data) {
                              console.log(data);
                              assert.deepEqual(data, {
                                status: 200,
                                message:
                                  'Object "' +
                                  filename +
                                  '" was deleted successfully from bucket "' +
                                  bucketName +
                                  '"'
                              });

                              provider
                                .deleteFile(bucketName, filenameTxt)
                                .then(function(data) {
                                  console.log(data);
                                  assert.deepEqual(data, {
                                    status: 200,
                                    message:
                                      'Object "' +
                                      filenameTxt +
                                      '" was deleted successfully from bucket "' +
                                      bucketName +
                                      '"'
                                  });

                                  provider
                                    .deleteBucket(bucketName)
                                    .then(function(data) {
                                      console.log(data);
                                      assert.deepEqual(data, {
                                        status: 200,
                                        message:
                                          'Bucket "' +
                                          bucketName +
                                          '" was deleted successfully'
                                      });
                                    })
                                    .catch(function(data) {
                                      return console.log(data);
                                    });
                                })
                                .catch(function(data) {
                                  return console.log(data);
                                });
                            })
                            .catch(function(data) {
                              return console.log(data);
                            });
                        })
                        .catch(function(data) {
                          return console.log(data);
                        });
                    })
                    .catch(function(data) {
                      return console.log(data);
                    });
                })
                .catch(function(data) {
                  return console.log(data);
                });
            })
            .catch(function(data) {
              return console.log(data);
            });
        })
        .catch(function(data) {
          return console.log(data);
        });
    })
    .catch(function(data) {
      return console.log(data);
    });
};

var simulateObjectCorruptionWorkflow = function simulateObjectCorruptionWorkflow(
  provider,
  bucketName,
  filename
) {
  provider
    .createBucket(bucketName)
    .then(function(data) {
      console.log(data);
      assert.deepEqual(data, {
        status: 201,
        message: 'Bucket "' + bucketName + '" was created successfully'
      });

      var txt = "This is a random text \n Second Line";

      var shouldSimulateFileCorruption = true;
      provider
        .createFileFromText(
          bucketName,
          filename,
          txt,
          shouldSimulateFileCorruption
        )
        .catch(function(data) {
          console.log(data);
          assert.deepEqual(data, {
            status: 400,
            message:
              'CRC32 validation error. Object "' +
              filename +
              '" could not be uploaded successfully'
          });

          provider
            .deleteFile(bucketName, filename)
            .then(function(data) {
              console.log(data);
              assert.deepEqual(data, {
                status: 200,
                message:
                  'Object "' +
                  filename +
                  '" was deleted successfully from bucket "' +
                  bucketName +
                  '"'
              });

              provider
                .deleteBucket(bucketName)
                .then(function(data) {
                  console.log(data);
                  assert.deepEqual(data, {
                    status: 200,
                    message:
                      'Bucket "' + bucketName + '" was deleted successfully'
                  });
                })
                .catch(function(data) {
                  return console.log(data);
                });
            })
            .catch(function(data) {
              return console.log(data);
            });
        });
    })
    .catch(function(data) {
      return console.log(data);
    });
};

var simulateBigFileUploadErrorWorkflow = function simulateBigFileUploadErrorWorkflow(
  provider,
  bucketName,
  filePath
) {
  provider
    .createBucket(bucketName)
    .then(function(data) {
      console.log(data);
      assert.deepEqual(data, {
        status: 201,
        message: 'Bucket "' + bucketName + '" was created successfully'
      });

      var shouldSimulateBigFileUploadError = true;
      provider
        .uploadFile(bucketName, filePath, shouldSimulateBigFileUploadError)
        .catch(function(data) {
          console.log(data);
          assert.deepEqual(data, {
            status: 400,
            message: 'Large File "' + filePath + '" upload was unsuccessful'
          });

          provider
            .deleteBucket(bucketName)
            .then(function(data) {
              console.log(data);
              assert.deepEqual(data, {
                status: 200,
                message: 'Bucket "' + bucketName + '" was deleted successfully'
              });
            })
            .catch(function(data) {
              return console.log(data);
            });
        });
    })
    .catch(function(data) {
      return console.log(data);
    });
};

var uploadBigFileWorkflow = function uploadBigFileWorkflow(
  provider,
  bucketName,
  filePath
) {
  provider
    .createBucket(bucketName)
    .then(function(data) {
      console.log(data);
      assert.deepEqual(data, {
        status: 201,
        message: 'Bucket "' + bucketName + '" was created successfully'
      });

      provider
        .uploadFile(bucketName, filePath)
        .then(function(data) {
          console.log(data);
          assert.deepEqual(data, {
            status: 200,
            message:
              'File "' +
              filePath +
              '" was uploaded successfully to bucket "' +
              bucketName +
              '"'
          });

          var filename = path.basename(filePath);
          provider
            .deleteFile(bucketName, filename)
            .then(function(data) {
              console.log(data);
              assert.deepEqual(data, {
                status: 200,
                message:
                  'Object "' +
                  filename +
                  '" was deleted successfully from bucket "' +
                  bucketName +
                  '"'
              });

              provider
                .deleteBucket(bucketName)
                .then(function(data) {
                  console.log(data);
                  assert.deepEqual(data, {
                    status: 200,
                    message:
                      'Bucket "' + bucketName + '" was deleted successfully'
                  });
                })
                .catch(function(data) {
                  return console.log(data);
                });
            })
            .catch(function(data) {
              return console.log(data);
            });
        })
        .catch(function(data) {
          return console.log(data);
        });
    })
    .catch(function(data) {
      return console.log(data);
    });
};

var rejectMissingParametersWorkflow = function rejectMissingParametersWorkflow(
  provider,
  bucketName,
  filename
) {
  provider.createBucket(bucketName).catch(function(data) {
    assert.deepEqual(data, {
      status: 400,
      message: "Invalid parameters"
    });
    provider.createFileFromText(bucketName, filename, {}).catch(function(data) {
      assert.deepEqual(data, {
        status: 400,
        message: "Invalid parameters"
      });
      provider.readFile(bucketName, filename).catch(function(data) {
        assert.deepEqual(data, {
          status: 400,
          message: "Invalid parameters"
        });
        provider.getListOfFiles(bucketName).catch(function(data) {
          assert.deepEqual(data, {
            status: 400,
            message: "Invalid parameters"
          });
          provider.deleteFile(bucketName, filename).catch(function(data) {
            assert.deepEqual(data, {
              status: 400,
              message: "Invalid parameters"
            });
            provider.deleteBucket(bucketName).catch(function(data) {
              assert.deepEqual(data, {
                status: 400,
                message: "Invalid parameters"
              });
            });
          });
        });
      });
    });
  });
};

var rejectUniversalApiWorkflow = function rejectUniversalApiWorkflow(
  provider,
  bucketName,
  filename
) {
  provider.createBucket(bucketName).catch(function(data) {
    assert.equal(data.status, 400);

    provider
      .createFileFromText(bucketName, filename, { attr1: 2 })
      .catch(function(data) {
        assert.equal(data.status, 400);

        provider.readFile(bucketName, filename).catch(function(data) {
          assert.equal(data.status, 400);

          provider.getListOfFiles(bucketName).catch(function(data) {
            assert.equal(data.status, 400);

            provider.deleteFile(bucketName, filename).catch(function(data) {
              assert.equal(data.status, 400);

              provider.deleteBucket(bucketName).catch(function(data) {
                assert.equal(data.status, 400);
              });
            });
          });
        });
      });
  });
};

module.exports = {
  resolveUniversalApiWorkflow: resolveUniversalApiWorkflow,
  simulateObjectCorruptionWorkflow: simulateObjectCorruptionWorkflow,
  uploadBigFileWorkflow: uploadBigFileWorkflow,
  simulateBigFileUploadErrorWorkflow: simulateBigFileUploadErrorWorkflow,
  rejectMissingParametersWorkflow: rejectMissingParametersWorkflow,
  rejectUniversalApiWorkflow: rejectUniversalApiWorkflow
};
