// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "url_loader_impl.h"
#include "base/logging.h"
#include "base/mac/scoped_nsautorelease_pool.h"

#import <Foundation/Foundation.h>

@interface URLLoaderConnectionDelegate : NSObject<NSURLConnectionDataDelegate>

@property(nonatomic) mojo::URLLoaderImpl::StartCallback startCallback;
@property(nonatomic, retain) NSURLRequest *originalRequest;

@end

@implementation URLLoaderConnectionDelegate {
  mojo::URLResponsePtr _response;
  mojo::ScopedDataPipeProducerHandle _producer;
}

@synthesize startCallback = _startCallback;
@synthesize originalRequest = _originalRequest;

- (void)connection:(NSURLConnection*)connection
    didReceiveResponse:(NSHTTPURLResponse*)response {
  _response = mojo::URLResponse::New();
  _response->status_code = response.statusCode;
  _response->url =
      mojo::String(self.originalRequest.URL.absoluteString.UTF8String);
  mojo::DataPipe pipe;
  _response->body = pipe.consumer_handle.Pass();
  _producer = pipe.producer_handle.Pass();
  [self.class updateDelegate:self asPending:YES];
}

- (void)connection:(NSURLConnection*)connection didReceiveData:(NSData*)data {
  if (!_startCallback.is_null()) {
    DCHECK(_response);
    _startCallback.Run(_response.Pass());
    _startCallback.reset();
    _response.reset();
  }
  uint32_t length = data.length;
  // TODO(eseidel): This can't work. The data pipe could be full, we need to
  // write an async writter for filling the pipe and use it here.
  MojoResult result = WriteDataRaw(_producer.get(), data.bytes, &length,
                                   MOJO_WRITE_DATA_FLAG_ALL_OR_NONE);
  // FIXME(csg): Handle buffers in case of failures
  DCHECK(result == MOJO_RESULT_OK);
  DCHECK(length == data.length);
}

- (void)connectionDidFinishLoading:(NSURLConnection*)connection {
  DCHECK(_response.is_null());
  DCHECK(_startCallback.is_null());
  _producer.reset();
  [self.class updateDelegate:self asPending:NO];
}

- (void)connection:(NSURLConnection*)connection
    didFailWithError:(NSError*)error {
  if (!_startCallback.is_null()) {
    if (_response.is_null()) {
      _response = mojo::URLResponse::New();
      _response->url = mojo::String(
          self.originalRequest.URL.absoluteString.UTF8String);
    }

    _response->error = mojo::NetworkError::New();
    _response->error->description =
        mojo::String(error.localizedDescription.UTF8String);

    _startCallback.Run(_response.Pass());
    _startCallback.reset();
  }

  _response.reset();
  _producer.reset();
  [self.class updateDelegate:self asPending:NO];
}

// Since the only reference to the producer end of a data pipe is held by the
// delegate, which itself has no strong reference, we put the in-flight requests
// in a collection that references these delegates while they are active.
+ (void)updateDelegate:(URLLoaderConnectionDelegate*)delegate
             asPending:(BOOL)pending {
  static NSMutableSet* pendingConnections = nil;
  static dispatch_once_t onceToken;
  dispatch_once(&onceToken, ^{
    pendingConnections = [[NSMutableSet alloc] init];
  });
  if (pending) {
    [pendingConnections addObject:delegate];
  } else {
    [pendingConnections removeObject:delegate];
  }
}

- (void)dealloc {
  [_originalRequest release];
  DCHECK(_response.is_null());
  DCHECK(_startCallback.is_null());
  _producer.reset();
  [super dealloc];
}

@end

namespace mojo {

URLLoaderImpl::URLLoaderImpl(InterfaceRequest<URLLoader> request)
    : binding_(this, request.Pass()),
      connection_delegate_(nullptr),
      pending_connection_(nullptr) {
  connection_delegate_ = [[URLLoaderConnectionDelegate alloc] init];
}

URLLoaderImpl::~URLLoaderImpl() {
  [(id)connection_delegate_ release];

  [(id)pending_connection_ cancel];
  [(id)pending_connection_ release];
}

void URLLoaderImpl::Start(URLRequestPtr request,
                          const StartCallback& callback) {
  base::mac::ScopedNSAutoreleasePool pool;

  NSURL* url = [NSURL URLWithString:@(request->url.data())];
  NSMutableURLRequest* req = [NSMutableURLRequest requestWithURL:url];

  req.HTTPMethod = @(request->method.data());

  URLLoaderConnectionDelegate* delegate =
      (URLLoaderConnectionDelegate*)connection_delegate_;

  NSURLConnection* connection =
      [NSURLConnection connectionWithRequest:req delegate:delegate];

  delegate.startCallback = callback;
  delegate.originalRequest = req;

  [connection start];

  pending_connection_ = [connection retain];
}

void URLLoaderImpl::FollowRedirect(const FollowRedirectCallback& callback) {
  base::mac::ScopedNSAutoreleasePool pool;
  DCHECK(false);
}

void URLLoaderImpl::QueryStatus(const QueryStatusCallback& callback) {
  base::mac::ScopedNSAutoreleasePool pool;
  DCHECK(false);
}

}  // namespace mojo
