/*
 *
 * 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 "GRXImmediateWriter.h"

#import "NSEnumerator+GRXUtil.h"

@implementation GRXImmediateWriter {
  NSEnumerator *_enumerator;
  NSError *_errorOrNil;
  id<GRXWriteable> _writeable;
}

@synthesize state = _state;

- (instancetype) init {
  return [self initWithEnumerator:nil error:nil]; // results in an empty writer.
}

// Designated initializer
- (instancetype)initWithEnumerator:(NSEnumerator *)enumerator error:(NSError *)errorOrNil {
  if (((self = [super init]))) {
    _enumerator = enumerator;
    _errorOrNil = errorOrNil;
    _state = GRXWriterStateNotStarted;
  }
  return self;
}

#pragma mark Convenience constructors

+ (instancetype)writerWithEnumerator:(NSEnumerator *)enumerator error:(NSError *)errorOrNil {
  return [[self alloc] initWithEnumerator:enumerator error:errorOrNil];
}

+ (GRXWriter *)writerWithEnumerator:(NSEnumerator *)enumerator {
  return [self writerWithEnumerator:enumerator error:nil];
}

+ (GRXWriter *)writerWithValueSupplier:(id (^)(void))block {
  return [self writerWithEnumerator:[NSEnumerator grx_enumeratorWithValueSupplier:block]];
}

+ (GRXWriter *)writerWithContainer:(id<NSFastEnumeration>)container {
  return [self writerWithEnumerator:[NSEnumerator grx_enumeratorWithContainer:container]];;
}

+ (GRXWriter *)writerWithValue:(id)value {
  return [self writerWithEnumerator:[NSEnumerator grx_enumeratorWithSingleValue:value]];
}

+ (GRXWriter *)writerWithError:(NSError *)error {
  return [self writerWithEnumerator:nil error:error];
}

+ (GRXWriter *)emptyWriter {
  return [self writerWithEnumerator:nil error:nil];
}

#pragma mark Conformance with GRXWriter

// Most of the complexity in this implementation is the result of supporting pause and resumption of
// the GRXWriter. It's an important feature for instances of GRXWriter that are backed by a
// container (which may be huge), or by a NSEnumerator (which may even be infinite).

- (void)writeUntilPausedOrStopped {
  id value;
  while (value = [_enumerator nextObject]) {
    [_writeable writeValue:value];
    // If the writeable has a reference to us, it might change our state to paused or finished.
    if (_state == GRXWriterStatePaused || _state == GRXWriterStateFinished) {
      return;
    }
  }
  [self finishWithError:_errorOrNil];
}

- (void)startWithWriteable:(id<GRXWriteable>)writeable {
  _state = GRXWriterStateStarted;
  _writeable = writeable;
  [self writeUntilPausedOrStopped];
}

- (void)finishWithError:(NSError *)errorOrNil {
  _state = GRXWriterStateFinished;
  _enumerator = nil;
  _errorOrNil = nil;
  id<GRXWriteable> writeable = _writeable;
  _writeable = nil;
  [writeable writesFinishedWithError:errorOrNil];
}

- (void)setState:(GRXWriterState)newState {
  // Manual transitions are only allowed from the started or paused states.
  if (_state == GRXWriterStateNotStarted || _state == GRXWriterStateFinished) {
    return;
  }

  switch (newState) {
    case GRXWriterStateFinished:
      _state = newState;
      _enumerator = nil;
      _errorOrNil = nil;
      // Per GRXWriter's contract, setting the state to Finished manually
      // means one doesn't wish the writeable to be messaged anymore.
      _writeable = nil;
      return;
    case GRXWriterStatePaused:
      _state = newState;
      return;
    case GRXWriterStateStarted:
      if (_state == GRXWriterStatePaused) {
        _state = newState;
        [self writeUntilPausedOrStopped];
      }
      return;
    case GRXWriterStateNotStarted:
      return;
  }
}

@end
