<commit_before>#include <node.h>
#include <v8.h>

#include "Application.h"
#include "SpotifyService/SpotifyService.h"
#include "NodeCallback.h"

#include "objects/node/StaticCallbackSetter.h"
#include "objects/spotify/PlaylistContainer.h"
#include "objects/node/NodePlaylist.h"
#include "objects/node/NodeTrack.h"
#include "objects/node/NodePlayer.h"
#include "objects/node/NodeAlbum.h"
#include "objects/node/NodeArtist.h"
#include "objects/node/NodeSearch.h"

extern "C" {
  #include "audio/audio.h"
}

using namespace v8;

Application* application;

Handle<Value> login(const Arguments& args) {
  HandleScope scope;
  String::Utf8Value v8User(args[0]->ToString());
  String::Utf8Value v8Password(args[1]->ToString());
  bool rememberMe = args[2]->ToBoolean()->Value();
  bool withRemembered = args[3]->ToBoolean()->Value();
  std::string user(*v8User);
  std::string password(*<PASSWORD>);
  application->spotifyService->login(user, password, rememberMe, withRemembered);
  return scope.Close(Undefined());
}

Handle<Value> logout(const Arguments& args) {
  HandleScope scope;
  auto callback = [] () { application->spotifyService->logout(); };
  application->spotifyService->executeSpotifyAPIcall(callback);
  return scope.Close(Undefined());
}

Handle<Value> ready(const Arguments& args) {
  HandleScope scope;
  Handle<Function> fun = Handle<Function>::Cast(args[0]);
  Persistent<Function> p = Persistent<Function>::New(fun);
  application->loginCallback = p;
  return scope.Close(Undefined());
}

Handle<Value> getPlaylists(const Arguments& args) {
  HandleScope scope;
  std::vector<std::shared_ptr<Playlist>> playlists = application->playlistContainer->getPlaylists();
  Local<Array> nPlaylists = Array::New(playlists.size());
  for(int i = 0; i < (int)playlists.size(); i++) {
    NodePlaylist* nodePlaylist = new NodePlaylist(playlists[i]);
    nPlaylists->Set(Number::New(i), nodePlaylist->getV8Object());
  }
  return scope.Close(nPlaylists);
}

Handle<Value> getStarred(const Arguments& args) {
  HandleScope scope;
  NodePlaylist* starredPlaylist = new NodePlaylist(application->playlistContainer->starredPlaylist);
  return scope.Close(starredPlaylist->getV8Object());
}

/**
 * Handle a NodeCallback sent to this thread. 
 * The handle should contain a NodeCallback struct
 **/
void resolveCallback(uv_async_t* handle, int status) {
  HandleScope scope;
  NodeCallback* nodeCallback = (NodeCallback*)handle->data;
  Handle<Function>* fun = nodeCallback->function;

  const unsigned int argc = 0;
  Local<Value> argv[argc] = { };
  if(!(*fun).IsEmpty() && (*fun)->IsCallable()) {
    //Check if an object is attached to the struct and if, use it as the scope.
    if(nodeCallback->object == 0 || nodeCallback->object->getV8Object().IsEmpty())
      (*fun)->Call(Context::GetCurrent()->Global(), argc, argv);
    else
      (*fun)->Call(nodeCallback->object->getV8Object(), argc, argv);
  }
  scope.Close(Undefined());
}

Handle<Value> rememberedUser(const Arguments& args) {
  HandleScope scope;
  if(application->spotifyService->rememberedUser != 0) {
    return scope.Close(String::New(application->spotifyService->rememberedUser));
  } else {<commit_msg>Callbacks are now called in the fashion of function(err, object) instead of mutating this<commit_after>#include <node.h>
#include <v8.h>

#include "Application.h"
#include "SpotifyService/SpotifyService.h"
#include "NodeCallback.h"

#include "objects/node/StaticCallbackSetter.h"
#include "objects/spotify/PlaylistContainer.h"
#include "objects/node/NodePlaylist.h"
#include "objects/node/NodeTrack.h"
#include "objects/node/NodePlayer.h"
#include "objects/node/NodeAlbum.h"
#include "objects/node/NodeArtist.h"
#include "objects/node/NodeSearch.h"

extern "C" {
  #include "audio/audio.h"
}

using namespace v8;

Application* application;

Handle<Value> login(const Arguments& args) {
  HandleScope scope;
  String::Utf8Value v8User(args[0]->ToString());
  String::Utf8Value v8Password(args[1]->ToString());
  bool rememberMe = args[2]->ToBoolean()->Value();
  bool withRemembered = args[3]->ToBoolean()->Value();
  std::string user(*v8User);
  std::string password(*<PASSWORD>);
  application->spotifyService->login(user, password, rememberMe, withRemembered);
  return scope.Close(Undefined());
}

Handle<Value> logout(const Arguments& args) {
  HandleScope scope;
  auto callback = [] () { application->spotifyService->logout(); };
  application->spotifyService->executeSpotifyAPIcall(callback);
  return scope.Close(Undefined());
}

Handle<Value> ready(const Arguments& args) {
  HandleScope scope;
  Handle<Function> fun = Handle<Function>::Cast(args[0]);
  Persistent<Function> p = Persistent<Function>::New(fun);
  application->loginCallback = p;
  return scope.Close(Undefined());
}

Handle<Value> getPlaylists(const Arguments& args) {
  HandleScope scope;
  std::vector<std::shared_ptr<Playlist>> playlists = application->playlistContainer->getPlaylists();
  Local<Array> nPlaylists = Array::New(playlists.size());
  for(int i = 0; i < (int)playlists.size(); i++) {
    NodePlaylist* nodePlaylist = new NodePlaylist(playlists[i]);
    nPlaylists->Set(Number::New(i), nodePlaylist->getV8Object());
  }
  return scope.Close(nPlaylists);
}

Handle<Value> getStarred(const Arguments& args) {
  HandleScope scope;
  NodePlaylist* starredPlaylist = new NodePlaylist(application->playlistContainer->starredPlaylist);
  return scope.Close(starredPlaylist->getV8Object());
}

/**
 * Handle a NodeCallback sent to this thread. 
 * The handle should contain a NodeCallback struct
 **/
void resolveCallback(uv_async_t* handle, int status) {
  HandleScope scope;
  NodeCallback* callbackStruct = (NodeCallback*)handle->data;
  Handle<Function>* callback = callbackStruct->function;

  //only execute if a callback is attached
  if(!(*callback).IsEmpty() && (*callback)->IsCallable()) {
    unsigned int argc;
    Handle<Value>* argv;
    //if the callback has a V8 object attach use it as the second argument for the callback
    //TODO: atm error is constantly undefined.
    if(callbackStruct->object != nullptr && !callbackStruct->object->getV8Object().IsEmpty()) {
      argc = 2;
      argv = new Handle<Value>[2];
      argv[0] = Undefined();
      argv[1] = callbackStruct->object->getV8Object();
    } else {
      argc = 1;
      argv = new Handle<Value>[1];
      argv[0] = Undefined();
    }
    
    (*callback)->Call(Context::GetCurrent()->Global(), argc, argv);
    delete[] argv;
  }
  scope.Close(Undefined());
}

Handle<Value> rememberedUser(const Arguments& args) {
  HandleScope scope;
  if(application->spotifyService->rememberedUser != 0) {
    return scope.Close(String::New(application->spotifyService->rememberedUser));
  } else {
{'fraction_non_alphanumeric': 0.15226765799256506, 'fraction_numerical': 0.006840148698884758, 'mean_word_length': 5.45489443378119, 'pattern_counts': {'":': 0, '<': 43, '<?xml version=': 0, '>': 110, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5589005', 'n_tokens_mistral': 2126, 'n_tokens_neox': 2101, 'n_words': 442}