#ifndef GITREMOTE_H
#define GITREMOTE_H
// generated from class_header.h
#include <nan.h>
#include <string>

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

#include "../include/remote.h"
#include "../include/repository.h"
#include "../include/signature.h"
#include "../include/remote_callbacks.h"
#include "../include/strarray.h"
#include "../include/refspec.h"
#include "../include/transport.h"
#include "../include/transfer_progress.h"

using namespace node;
using namespace v8;

class GitRemote : public ObjectWrap {
public:

  static Persistent<Function> constructor_template;
  static void InitializeComponent (Handle<v8::Object> target);

  git_remote *GetValue();
  git_remote **GetRefValue();

  static Handle<Value> New(void *raw, bool selfFreeing);
  bool selfFreeing;

private:
  GitRemote(git_remote *raw, bool selfFreeing);
  ~GitRemote();

  static NAN_METHOD(JSNewFunction);


  static NAN_METHOD(AddFetch);

  static NAN_METHOD(AddPush);

  static NAN_METHOD(Autotag);

  static NAN_METHOD(CheckCert);

  static NAN_METHOD(ClearRefspecs);

  static NAN_METHOD(Connect);

  static NAN_METHOD(Connected);

  struct CreateBaton {
    int error_code;
    const git_error* error;
    git_remote * out;
    git_repository * repo;
    const char * name;
    const char * url;
  };
  class CreateWorker : public NanAsyncWorker {
  public:
    CreateWorker(
      CreateBaton *_baton,
      NanCallback *callback
    ) : NanAsyncWorker(callback)
      , baton(_baton) {};
    ~CreateWorker() {};
    void Execute();
    void HandleOKCallback();

  private:
    CreateBaton *baton;
  };

  static NAN_METHOD(Create);

  struct CreateAnonymousBaton {
    int error_code;
    const git_error* error;
    git_remote * out;
    git_repository * repo;
    const char * url;
    const char * fetch;
  };
  class CreateAnonymousWorker : public NanAsyncWorker {
  public:
    CreateAnonymousWorker(
      CreateAnonymousBaton *_baton,
      NanCallback *callback
    ) : NanAsyncWorker(callback)
      , baton(_baton) {};
    ~CreateAnonymousWorker() {};
    void Execute();
    void HandleOKCallback();

  private:
    CreateAnonymousBaton *baton;
  };

  static NAN_METHOD(CreateAnonymous);

  struct CreateWithFetchspecBaton {
    int error_code;
    const git_error* error;
    git_remote * out;
    git_repository * repo;
    const char * name;
    const char * url;
    const char * fetch;
  };
  class CreateWithFetchspecWorker : public NanAsyncWorker {
  public:
    CreateWithFetchspecWorker(
      CreateWithFetchspecBaton *_baton,
      NanCallback *callback
    ) : NanAsyncWorker(callback)
      , baton(_baton) {};
    ~CreateWithFetchspecWorker() {};
    void Execute();
    void HandleOKCallback();

  private:
    CreateWithFetchspecBaton *baton;
  };

  static NAN_METHOD(CreateWithFetchspec);

  static NAN_METHOD(Delete);

  static NAN_METHOD(Disconnect);

  static NAN_METHOD(Download);

  struct DupBaton {
    int error_code;
    const git_error* error;
    git_remote * dest;
    git_remote * source;
  };
  class DupWorker : public NanAsyncWorker {
  public:
    DupWorker(
      DupBaton *_baton,
      NanCallback *callback
    ) : NanAsyncWorker(callback)
      , baton(_baton) {};
    ~DupWorker() {};
    void Execute();
    void HandleOKCallback();

  private:
    DupBaton *baton;
  };

  static NAN_METHOD(Dup);

  struct FetchBaton {
    int error_code;
    const git_error* error;
    git_remote * remote;
    const git_signature * signature;
    const char * reflog_message;
  };
  class FetchWorker : public NanAsyncWorker {
  public:
    FetchWorker(
      FetchBaton *_baton,
      NanCallback *callback
    ) : NanAsyncWorker(callback)
      , baton(_baton) {};
    ~FetchWorker() {};
    void Execute();
    void HandleOKCallback();

  private:
    FetchBaton *baton;
  };

  static NAN_METHOD(Fetch);

  static NAN_METHOD(GetCallbacks);

  struct GetFetchRefspecsBaton {
    int error_code;
    const git_error* error;
    git_strarray * array;
    const git_remote * remote;
  };
  class GetFetchRefspecsWorker : public NanAsyncWorker {
  public:
    GetFetchRefspecsWorker(
      GetFetchRefspecsBaton *_baton,
      NanCallback *callback
    ) : NanAsyncWorker(callback)
      , baton(_baton) {};
    ~GetFetchRefspecsWorker() {};
    void Execute();
    void HandleOKCallback();

  private:
    GetFetchRefspecsBaton *baton;
  };

  static NAN_METHOD(GetFetchRefspecs);

  struct GetPushRefspecsBaton {
    int error_code;
    const git_error* error;
    git_strarray * array;
    const git_remote * remote;
  };
  class GetPushRefspecsWorker : public NanAsyncWorker {
  public:
    GetPushRefspecsWorker(
      GetPushRefspecsBaton *_baton,
      NanCallback *callback
    ) : NanAsyncWorker(callback)
      , baton(_baton) {};
    ~GetPushRefspecsWorker() {};
    void Execute();
    void HandleOKCallback();

  private:
    GetPushRefspecsBaton *baton;
  };

  static NAN_METHOD(GetPushRefspecs);

  static NAN_METHOD(GetRefspec);

  static NAN_METHOD(InitCallbacks);

  static NAN_METHOD(IsValidName);

  struct ListBaton {
    int error_code;
    const git_error* error;
    git_strarray * out;
    git_repository * repo;
  };
  class ListWorker : public NanAsyncWorker {
  public:
    ListWorker(
      ListBaton *_baton,
      NanCallback *callback
    ) : NanAsyncWorker(callback)
      , baton(_baton) {};
    ~ListWorker() {};
    void Execute();
    void HandleOKCallback();

  private:
    ListBaton *baton;
  };

  static NAN_METHOD(List);

  struct LoadBaton {
    int error_code;
    const git_error* error;
    git_remote * out;
    git_repository * repo;
    const char * name;
  };
  class LoadWorker : public NanAsyncWorker {
  public:
    LoadWorker(
      LoadBaton *_baton,
      NanCallback *callback
    ) : NanAsyncWorker(callback)
      , baton(_baton) {};
    ~LoadWorker() {};
    void Execute();
    void HandleOKCallback();

  private:
    LoadBaton *baton;
  };

  static NAN_METHOD(Load);

  static NAN_METHOD(Name);

  static NAN_METHOD(Owner);

  static NAN_METHOD(Pushurl);

  static NAN_METHOD(RefspecCount);

  static NAN_METHOD(Save);

  static NAN_METHOD(SetAutotag);

  static NAN_METHOD(SetCallbacks);

  static NAN_METHOD(SetPushurl);

  static NAN_METHOD(SetTransport);

  static NAN_METHOD(SetUpdateFetchhead);

  static NAN_METHOD(SetUrl);

  static NAN_METHOD(Stats);

  static NAN_METHOD(Stop);

  static NAN_METHOD(SupportedUrl);

  static NAN_METHOD(UpdateFetchhead);

  static NAN_METHOD(UpdateTips);

  static NAN_METHOD(Url);

  static NAN_METHOD(ValidUrl);
  git_remote *raw;
};

#endif
