/*
 *  Copyright 2014 The WebRTC Project Authors. All rights reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#import "ARDAppEngineClient.h"

#import "sdk/objc/base/RTCLogging.h"

#import "ARDJoinResponse.h"
#import "ARDMessageResponse.h"
#import "ARDSignalingMessage.h"
#import "ARDUtilities.h"

// TODO(tkchin): move these to a configuration object.
static NSString *const kARDRoomServerHostUrl = @"https://appr.tc";
static NSString *const kARDRoomServerJoinFormat = @"https://appr.tc/join/%@";
static NSString *const kARDRoomServerJoinFormatLoopback =
    @"https://appr.tc/join/%@?debug=loopback";
static NSString *const kARDRoomServerMessageFormat =
    @"https://appr.tc/message/%@/%@";
static NSString *const kARDRoomServerLeaveFormat =
    @"https://appr.tc/leave/%@/%@";

static NSString *const kARDAppEngineClientErrorDomain = @"ARDAppEngineClient";
static NSInteger const kARDAppEngineClientErrorBadResponse = -1;

@implementation ARDAppEngineClient

#pragma mark - ARDRoomServerClient

- (void)joinRoomWithRoomId:(NSString *)roomId
                isLoopback:(BOOL)isLoopback
         completionHandler:(void (^)(ARDJoinResponse *response,
                                     NSError *error))completionHandler {
  NSParameterAssert(roomId.length);

  NSString *urlString = nil;
  if (isLoopback) {
    urlString =
        [NSString stringWithFormat:kARDRoomServerJoinFormatLoopback, roomId];
  } else {
    urlString = [NSString stringWithFormat:kARDRoomServerJoinFormat, roomId];
  }

  NSURL *roomURL = [NSURL URLWithString:urlString];
  RTCLog(@"Joining room:%@ on room server.", roomId);
  NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:roomURL];
  request.HTTPMethod = @"POST";
  [NSURLConnection
       sendAsyncRequest:request
      completionHandler:^(
          NSURLResponse *response __unused, NSData *data, NSError *error) {
        if (error) {
          if (completionHandler) {
            completionHandler(nil, error);
          }
          return;
        }
        ARDJoinResponse *joinResponse =
            [ARDJoinResponse responseFromJSONData:data];
        if (!joinResponse) {
          if (completionHandler) {
            NSError *error = [[self class] badResponseError];
            completionHandler(nil, error);
          }
          return;
        }
        if (completionHandler) {
          completionHandler(joinResponse, nil);
        }
      }];
}

- (void)sendMessage:(ARDSignalingMessage *)message
            forRoomId:(NSString *)roomId
             clientId:(NSString *)clientId
    completionHandler:(void (^)(ARDMessageResponse *response,
                                NSError *error))completionHandler {
  NSParameterAssert(message);
  NSParameterAssert(roomId.length);
  NSParameterAssert(clientId.length);

  NSData *data = [message JSONData];
  NSString *urlString =
      [NSString stringWithFormat:kARDRoomServerMessageFormat, roomId, clientId];
  NSURL *url = [NSURL URLWithString:urlString];
  RTCLog(@"C->RS POST: %@", message);
  NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
  request.HTTPMethod = @"POST";
  request.HTTPBody = data;
  [NSURLConnection
       sendAsyncRequest:request
      completionHandler:^(
          NSURLResponse *response __unused, NSData *data, NSError *error) {
        if (error) {
          if (completionHandler) {
            completionHandler(nil, error);
          }
          return;
        }
        ARDMessageResponse *messageResponse =
            [ARDMessageResponse responseFromJSONData:data];
        if (!messageResponse) {
          if (completionHandler) {
            NSError *error = [[self class] badResponseError];
            completionHandler(nil, error);
          }
          return;
        }
        if (completionHandler) {
          completionHandler(messageResponse, nil);
        }
      }];
}

- (void)leaveRoomWithRoomId:(NSString *)roomId
                   clientId:(NSString *)clientId
          completionHandler:(void (^)(NSError *error))completionHandler {
  NSParameterAssert(roomId.length);
  NSParameterAssert(clientId.length);

  NSString *urlString =
      [NSString stringWithFormat:kARDRoomServerLeaveFormat, roomId, clientId];
  NSURL *url = [NSURL URLWithString:urlString];
  NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
  request.HTTPMethod = @"POST";

  RTCLog(@"C->RS: BYE");
  __block NSError *error = nil;

  // We want a synchronous request so that we know that we've left the room on
  // room server before we do any further work.
  dispatch_semaphore_t sem = dispatch_semaphore_create(0);
  [NSURLConnection
       sendAsyncRequest:request
      completionHandler:^(
          NSURLResponse *response __unused, NSData *data __unused, NSError *e) {
        if (e) {
          error = e;
        }
        dispatch_semaphore_signal(sem);
      }];

  dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
  if (error) {
    RTCLogError(@"Error leaving room %@ on room server: %@",
                roomId,
                error.localizedDescription);
    if (completionHandler) {
      completionHandler(error);
    }
    return;
  }
  RTCLog(@"Left room:%@ on room server.", roomId);
  if (completionHandler) {
    completionHandler(nil);
  }
}

#pragma mark - Private

+ (NSError *)badResponseError {
  NSError *error = [[NSError alloc]
      initWithDomain:kARDAppEngineClientErrorDomain
                code:kARDAppEngineClientErrorBadResponse
            userInfo:@{
              NSLocalizedDescriptionKey : @"Error parsing response.",
            }];
  return error;
}

@end
