/*
 *
 * Copyright 2015 gRPC authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

#import "GRXWriteable.h"

@implementation GRXWriteable {
  GRXValueHandler _valueHandler;
  GRXCompletionHandler _completionHandler;
}

+ (instancetype)writeableWithSingleHandler:(GRXSingleHandler)handler {
  if (!handler) {
    return [[self alloc] init];
  }
  // We nilify this variable when the block is invoked, so that handler is only invoked once even if
  // the writer tries to write multiple values.
  __block GRXEventHandler eventHandler = ^(BOOL done, id value, NSError *error) {
    // Nillify eventHandler before invoking handler, in case the latter causes the former to be
    // executed recursively. Because blocks can be deallocated even during execution, we have to
    // first retain handler locally to guarantee it's valid.
    // TODO(jcanizales): Just turn this craziness into a simple subclass of GRXWriteable.
    GRXSingleHandler singleHandler = handler;
    eventHandler = nil;

    if (value) {
      singleHandler(value, nil);
    } else if (error) {
      singleHandler(nil, error);
    } else {
      NSDictionary *userInfo = @{
        NSLocalizedDescriptionKey: @"The writer finished without producing any value."
      };
      // Even though RxLibrary is independent of gRPC, the domain and code here are, for the moment,
      // set to the values of kGRPCErrorDomain and GRPCErrorCodeInternal. This way, the error formed
      // is the one user of gRPC would expect if the server failed to produce a response.
      //
      // TODO(jcanizales): Figure out a way to keep errors of RxLibrary generic without making users
      // of gRPC take care of two different error domains and error code enums. A possibility is to
      // add error handling to GRXWriters or GRXWriteables, and use them to translate errors between
      // the two domains.
      static NSString *kGRPCErrorDomain = @"io.grpc";
      static NSUInteger kGRPCErrorCodeInternal = 13;
      singleHandler(nil, [NSError errorWithDomain:kGRPCErrorDomain
                                             code:kGRPCErrorCodeInternal
                                         userInfo:userInfo]);
    }
  };
  return [self writeableWithEventHandler:^(BOOL done, id value, NSError *error) {
    if (eventHandler) {
      eventHandler(done, value, error);
    }
  }];
}

+ (instancetype)writeableWithEventHandler:(GRXEventHandler)handler {
  if (!handler) {
    return [[self alloc] init];
  }
  return [[self alloc] initWithValueHandler:^(id value) {
    handler(NO, value, nil);
  } completionHandler:^(NSError *errorOrNil) {
    handler(YES, nil, errorOrNil);
  }];
}

- (instancetype)init {
  return [self initWithValueHandler:nil completionHandler:nil];
}

// Designated initializer
- (instancetype)initWithValueHandler:(GRXValueHandler)valueHandler
                   completionHandler:(GRXCompletionHandler)completionHandler {
  if ((self = [super init])) {
    _valueHandler = valueHandler;
    _completionHandler = completionHandler;
  }
  return self;
}

- (void)writeValue:(id)value {
  if (_valueHandler) {
    _valueHandler(value);
  }
}

- (void)writesFinishedWithError:(NSError *)errorOrNil {
  if (_completionHandler) {
    _completionHandler(errorOrNil);
  }
}
@end
