// This is a generated file, modify: generate/templates/templates/class_header.h

#ifndef GITSTASH_H
#define GITSTASH_H
#include <nan.h>
#include <string>
#include <queue>
#include <utility>
#include <unordered_map>
#include <sstream>

#include "async_baton.h"
#include "async_worker.h"
#include "context.h"
#include "lock_master.h"
#include "nodegit_wrapper.h"
#include "promise_completion.h"
#include "reference_counter.h"

extern "C" {
#include <git2.h>
}

#include "../include/typedefs.h"

#include "../include/repository.h"
#include "../include/stash_apply_options.h"
#include "../include/oid.h"
#include "../include/signature.h"

using namespace node;
using namespace v8;


class GitStash : public
  Nan::ObjectWrap
{
   public:
    static void InitializeComponent (v8::Local<v8::Object> target, nodegit::Context *nodegitContext);

              static int Foreach_callback_cppCallback (
      size_t index
      ,
       const char * message
      ,
       const git_oid * stash_id
      ,
       void * payload
      );

    static void Foreach_callback_cancelAsync(void *baton);
    static void Foreach_callback_async(void *baton);
    static void Foreach_callback_promiseCompleted(bool isFulfilled, nodegit::AsyncBaton *_baton, v8::Local<v8::Value> result);
    class Foreach_CallbackBaton : public nodegit::AsyncBatonWithResult<int> {
    public:
      size_t index;
      const char * message;
      const git_oid * stash_id;
      void * payload;
 
      Foreach_CallbackBaton(const int &defaultResult)
        : nodegit::AsyncBatonWithResult<int>(defaultResult) {
        }
    };
                 

  private:

    struct ApplyBaton {
      int error_code;
      const git_error* error;
      git_repository * repo;
      size_t index;
      const git_stash_apply_options * options;
    };
    class ApplyWorker : public nodegit::AsyncWorker {
      public:
        ApplyWorker(
            ApplyBaton *_baton,
            Nan::Callback *callback
        ) : nodegit::AsyncWorker(callback, "nodegit:AsyncWorker:GitStash:Apply")
          , baton(_baton) {};
        ~ApplyWorker() {};
        void Execute();
        void HandleErrorCallback();
        void HandleOKCallback();
        nodegit::LockMaster AcquireLocks();

      private:
        ApplyBaton *baton;
    };

    static NAN_METHOD(Apply);

    struct DropBaton {
      int error_code;
      const git_error* error;
      git_repository * repo;
      size_t index;
    };
    class DropWorker : public nodegit::AsyncWorker {
      public:
        DropWorker(
            DropBaton *_baton,
            Nan::Callback *callback
        ) : nodegit::AsyncWorker(callback, "nodegit:AsyncWorker:GitStash:Drop")
          , baton(_baton) {};
        ~DropWorker() {};
        void Execute();
        void HandleErrorCallback();
        void HandleOKCallback();
        nodegit::LockMaster AcquireLocks();

      private:
        DropBaton *baton;
    };

    static NAN_METHOD(Drop);

    struct ForeachBaton {
      int error_code;
      const git_error* error;
      git_repository * repo;
      git_stash_cb callback;
      void * payload;
    };
    class ForeachWorker : public nodegit::AsyncWorker {
      public:
        ForeachWorker(
            ForeachBaton *_baton,
            Nan::Callback *callback
        ) : nodegit::AsyncWorker(callback, "nodegit:AsyncWorker:GitStash:Foreach")
          , baton(_baton) {};
        ~ForeachWorker() {};
        void Execute();
        void HandleErrorCallback();
        void HandleOKCallback();
        nodegit::LockMaster AcquireLocks();

      private:
        ForeachBaton *baton;
    };

    static NAN_METHOD(Foreach);

    struct PopBaton {
      int error_code;
      const git_error* error;
      git_repository * repo;
      size_t index;
      const git_stash_apply_options * options;
    };
    class PopWorker : public nodegit::AsyncWorker {
      public:
        PopWorker(
            PopBaton *_baton,
            Nan::Callback *callback
        ) : nodegit::AsyncWorker(callback, "nodegit:AsyncWorker:GitStash:Pop")
          , baton(_baton) {};
        ~PopWorker() {};
        void Execute();
        void HandleErrorCallback();
        void HandleOKCallback();
        nodegit::LockMaster AcquireLocks();

      private:
        PopBaton *baton;
    };

    static NAN_METHOD(Pop);

    struct SaveBaton {
      int error_code;
      const git_error* error;
      git_oid * out;
      git_repository * repo;
      const git_signature * stasher;
      const char * message;
      uint32_t flags;
    };
    class SaveWorker : public nodegit::AsyncWorker {
      public:
        SaveWorker(
            SaveBaton *_baton,
            Nan::Callback *callback
        ) : nodegit::AsyncWorker(callback, "nodegit:AsyncWorker:GitStash:Save")
          , baton(_baton) {};
        ~SaveWorker() {};
        void Execute();
        void HandleErrorCallback();
        void HandleOKCallback();
        nodegit::LockMaster AcquireLocks();

      private:
        SaveBaton *baton;
    };

    static NAN_METHOD(Save);

    struct Foreach_globalPayload {
      Nan::Callback * callback;

      Foreach_globalPayload() {
        callback = NULL;
      }

      ~Foreach_globalPayload() {
        if (callback != NULL) {
          delete callback;
        }
      }
    };
};

#endif
