#include "SamiApiClient.h"
using namespace Tizen::Base;
using namespace Tizen::Base::Utility;

namespace Swagger {

SamiApiClient::SamiApiClient() {
   enc = new Utf8Encoding();
}

void
SamiApiClient::success(void (*success) (HttpResponse*, void (*cb)(void*, SamiError*)), void (*cb)(void*, SamiError*)) {
  this->successFunction = success;
  this->cb = cb;
}

SamiApiClient::~SamiApiClient() {
  if(enc)
    delete enc;
}

result
SamiApiClient::execute(String host, String path, String method, IMap* queryParams, String* body, IMap* headerParams, IMap* formParams, String contentType) {
  NetHttpMethod httpMethod;
  if(method.Equals(L"GET", false)) {
    httpMethod = NET_HTTP_METHOD_GET;
  }
  else if(method.Equals(L"PUT", false)) {
    httpMethod = NET_HTTP_METHOD_PUT;
  }
  else if(method.Equals(L"POST", false)) {
    httpMethod = NET_HTTP_METHOD_POST;
  }
  else if(method.Equals(L"DELETE", false)) {
    httpMethod = NET_HTTP_METHOD_DELETE;
  }
  else if(method.Equals(L"OPTIONS", false)) {
    httpMethod = NET_HTTP_METHOD_OPTIONS;
  }
  else if(method.Equals(L"HEAD", false)) {
    httpMethod = NET_HTTP_METHOD_HEAD;
  }
  else if(method.Equals(L"TRACE", false)) {
    httpMethod = NET_HTTP_METHOD_TRACE;
  }

  String uri = String(host);
  uri.Append(path);

  HttpSession* __pHttpSession = null;
  HttpTransaction* pHttpTransaction = null;
  HttpRequest* pHttpRequest = null;

  if (__pHttpSession == null) {
    __pHttpSession = new (std::nothrow) HttpSession();
    __pHttpSession->Construct(NET_HTTP_SESSION_MODE_NORMAL, null, uri, null);
    __pHttpSession->SetAutoRedirectionEnabled(true);
  }
  pHttpTransaction = __pHttpSession->OpenTransactionN();
  pHttpTransaction->AddHttpTransactionListener(*this);

  pHttpRequest = const_cast< HttpRequest* >(pHttpTransaction->GetRequest());

  HttpHeader *pHeader = pHttpRequest->GetHeader();
  if(contentType != null && !contentType.Equals(L"", true)) {
    pHeader->AddField(L"Accept", contentType);
  }
  if(queryParams != null) {
    IMapEnumerator* pMapEnum = queryParams->GetMapEnumeratorN();
    String queryParam = L"";
    while (pMapEnum->MoveNext() == E_SUCCESS) {
      if(queryParam.GetLength() == 0)
        queryParam.Append(L"?");
      else
        queryParam.Append(L"&");

      String* pKey = static_cast< String* > (pMapEnum->GetKey());
      String* pValue = static_cast< String* > (pMapEnum->GetValue());
      String encoded;
      UrlEncoder::Encode(*pKey, L"UTF-8", encoded);

      queryParam.Append(encoded);
      queryParam.Append("=");
      UrlEncoder::Encode(*pValue, L"UTF-8", encoded);
      queryParam.Append(encoded);
    }
    uri.Append(queryParam);
    delete queryParams;
  }
  if(headerParams != null) {
    IMapEnumerator* pMapEnum = headerParams->GetMapEnumeratorN();
    while (pMapEnum->MoveNext() == E_SUCCESS) {
      String* pKey = static_cast< String* > (pMapEnum->GetKey());
      String* pValue = static_cast< String* > (pMapEnum->GetValue());
      pHeader->AddField(*pKey, *pValue);
    }
    delete headerParams;
  }
  if(body != null) {
    HttpStringEntity * pEntity = new HttpStringEntity();
    String* cp = new String(*body);
    result res = pEntity->Construct(*body, L"application/json", "utf-8", *enc);
    res = pHttpRequest->SetEntity(*pEntity);
  }

  pHttpRequest->SetUri(uri);
  pHttpRequest->SetMethod(httpMethod);

  AppLog("%ls", uri.GetPointer());
  return pHttpTransaction->Submit();
}

void
SamiApiClient::OnTransactionCompleted(HttpSession& httpSession, HttpTransaction& pHttpTransaction) {
  HttpResponse* pHttpResponse = pHttpTransaction.GetResponse();

  if(successFunction != null) {
    successFunction(pHttpResponse, cb);
  }
  delete &httpSession;
  delete &pHttpTransaction;
}

} /* namespace Swagger */
