// Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// Normally, we'd "import <Foundation/Foundation.h>"
// but that would mean that ffigen would process every file in the Foundation
// framework, which is huge. So just import the headers that we need.
#import <Foundation/NSObject.h>
#import <Foundation/NSURLSession.h>


/**
 * An object used to communicate redirect information to Dart code.
 *
 * The flow is:
 *  1. CUPHTTPClientDelegate receives a message from the URL Loading System.
 *  2. CUPHTTPClientDelegate creates a new CUPHTTPForwardedDelegate subclass.
 *  3. CUPHTTPClientDelegate sends the CUPHTTPForwardedDelegate to the
 *    configured Dart_Port.
 *  4. CUPHTTPClientDelegate waits on CUPHTTPForwardedDelegate.lock
 *  5. When the Dart code is done process the message received on the port,
 *    it calls [CUPHTTPForwardedDelegate finish*], which releases the lock.
 *  6. CUPHTTPClientDelegate continues running.
 */
@interface CUPHTTPForwardedDelegate : NSObject
- (id) initWithSession:(NSURLSession *)session
                  task:(NSURLSessionTask *) task;

/**
 * Indicates that the task should continue executing using the given request.
 */
- (void) finish;;

@property (readonly) NSURLSession *session;
@property (readonly) NSURLSessionTask *task;

// This property is meant to be used only by CUPHTTPClientDelegate.
@property (readonly) NSLock *lock;

@end

@interface CUPHTTPForwardedRedirect : CUPHTTPForwardedDelegate

- (id) initWithSession:(NSURLSession *)session
                  task:(NSURLSessionTask *) task
              response:(NSHTTPURLResponse *)response
               request:(NSURLRequest *)request;

/**
 * Indicates that the task should continue executing using the given request.
 * If the request is NIL then the redirect is not followed and the task is
 * complete.
 */
- (void) finishWithRequest:(nullable NSURLRequest *) request;

@property (readonly) NSHTTPURLResponse *response;
@property (readonly) NSURLRequest *request;

// This property is meant to be used only by CUPHTTPClientDelegate.
@property (readonly) NSURLRequest *redirectRequest;

@end

@interface CUPHTTPForwardedResponse : CUPHTTPForwardedDelegate

- (id) initWithSession:(NSURLSession *)session
                  task:(NSURLSessionTask *) task
              response:(NSURLResponse *)response;

- (void) finishWithDisposition:(NSURLSessionResponseDisposition) disposition;

@property (readonly) NSURLResponse *response;

// This property is meant to be used only by CUPHTTPClientDelegate.
@property (readonly) NSURLSessionResponseDisposition disposition;

@end

@interface CUPHTTPForwardedData : CUPHTTPForwardedDelegate

- (id) initWithSession:(NSURLSession *)session
                  task:(NSURLSessionTask *) task
                  data:(NSData *)data;

@property (readonly) NSData* data;

@end


@interface CUPHTTPForwardedComplete : CUPHTTPForwardedDelegate

- (id) initWithSession:(NSURLSession *)session
                  task:(NSURLSessionTask *) task
                 error:(nullable NSError *)error;

@property (nullable, readonly) NSError* error;

@end

@interface CUPHTTPForwardedFinishedDownloading : CUPHTTPForwardedDelegate

- (id) initWithSession:(NSURLSession *)session
          downloadTask:(NSURLSessionDownloadTask *)downloadTask
                   url:(NSURL *)location;

@property (readonly) NSURL* location;

@end

@interface CUPHTTPForwardedWebSocketOpened : CUPHTTPForwardedDelegate

- (id) initWithSession:(NSURLSession *)session
         webSocketTask:(NSURLSessionWebSocketTask *)webSocketTask
   didOpenWithProtocol:(nullable NSString *)protocol;

@property (nullable, readonly) NSString* protocol;

@end

@interface CUPHTTPForwardedWebSocketClosed : CUPHTTPForwardedDelegate

- (id) initWithSession:(NSURLSession *)session
         webSocketTask:(NSURLSessionWebSocketTask *)webSocketTask
                  code:(NSURLSessionWebSocketCloseCode)closeCode
                reason:(NSData *)reason;

@property (readonly) NSURLSessionWebSocketCloseCode closeCode;
@property (nullable, readonly) NSData* reason;

@end
