// Copyright 2014 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.

#import "base/ios/crb_protocol_observers.h"

#include <objc/runtime.h>
#include <stddef.h>
#include <algorithm>
#include <vector>

#include "base/logging.h"
#include "base/mac/scoped_nsobject.h"
#include "base/stl_util.h"

@interface CRBProtocolObservers () {
  base::scoped_nsobject<Protocol> _protocol;
  // ivars declared here are private to the implementation but must be
  // public for allowing the C++ |Iterator| class access to those ivars.
 @public
  // vector of weak pointers to observers.
  std::vector<__unsafe_unretained id> _observers;
  // The nested level of observer iteration.
  // A depth of 0 means nobody is currently iterating on the list of observers.
  int _invocationDepth;
}

// Removes nil observers from the list and is called when the
// |_invocationDepth| reaches 0.
- (void)compact;

@end

namespace {

class Iterator {
 public:
  explicit Iterator(CRBProtocolObservers* protocol_observers);
  ~Iterator();
  id GetNext();

 private:
  CRBProtocolObservers* protocol_observers_;
  size_t index_;
  size_t max_index_;
};

Iterator::Iterator(CRBProtocolObservers* protocol_observers)
    : protocol_observers_(protocol_observers),
      index_(0),
      max_index_(protocol_observers->_observers.size()) {
  DCHECK(protocol_observers_);
  ++protocol_observers->_invocationDepth;
}

Iterator::~Iterator() {
  if (protocol_observers_ && --protocol_observers_->_invocationDepth == 0)
    [protocol_observers_ compact];
}

id Iterator::GetNext() {
  if (!protocol_observers_)
    return nil;
  auto& observers = protocol_observers_->_observers;
  // Skip nil elements.
  size_t max_index = std::min(max_index_, observers.size());
  while (index_ < max_index && !observers[index_])
    ++index_;
  return index_ < max_index ? observers[index_++] : nil;
}
}

@interface CRBProtocolObservers ()

// Designated initializer.
- (id)initWithProtocol:(Protocol*)protocol;

@end

@implementation CRBProtocolObservers

+ (instancetype)observersWithProtocol:(Protocol*)protocol {
  return [[[self alloc] initWithProtocol:protocol] autorelease];
}

- (id)init {
  NOTREACHED();
  return nil;
}

- (id)initWithProtocol:(Protocol*)protocol {
  self = [super init];
  if (self) {
    _protocol.reset([protocol retain]);
  }
  return self;
}

- (Protocol*)protocol {
  return _protocol.get();
}

- (void)addObserver:(id)observer {
  DCHECK(observer);
  DCHECK([observer conformsToProtocol:self.protocol]);

  if (base::ContainsValue(_observers, observer))
    return;

  _observers.push_back(observer);
}

- (void)removeObserver:(id)observer {
  DCHECK(observer);
  auto it = std::find(_observers.begin(), _observers.end(), observer);
  if (it != _observers.end()) {
    if (_invocationDepth)
      *it = nil;
    else
      _observers.erase(it);
  }
}

- (BOOL)empty {
  int count = 0;
  for (id observer : _observers) {
    if (observer != nil)
      ++count;
  }
  return count == 0;
}

#pragma mark - NSObject

- (NSMethodSignature*)methodSignatureForSelector:(SEL)selector {
  NSMethodSignature* signature = [super methodSignatureForSelector:selector];
  if (signature)
    return signature;

  // Look for a required method in the protocol. protocol_getMethodDescription
  // returns a struct whose fields are null if a method for the selector was
  // not found.
  struct objc_method_description description =
      protocol_getMethodDescription(self.protocol, selector, YES, YES);
  if (description.types)
    return [NSMethodSignature signatureWithObjCTypes:description.types];

  // Look for an optional method in the protocol.
  description = protocol_getMethodDescription(self.protocol, selector, NO, YES);
  if (description.types)
    return [NSMethodSignature signatureWithObjCTypes:description.types];

  // There is neither a required nor optional method with this selector in the
  // protocol, so invoke -[NSObject doesNotRecognizeSelector:] to raise
  // NSInvalidArgumentException.
  [self doesNotRecognizeSelector:selector];
  return nil;
}

- (void)forwardInvocation:(NSInvocation*)invocation {
  DCHECK(invocation);
  if (_observers.empty())
    return;
  SEL selector = [invocation selector];
  Iterator it(self);
  id observer;
  while ((observer = it.GetNext()) != nil) {
    if ([observer respondsToSelector:selector])
      [invocation invokeWithTarget:observer];
  }
}

- (void)executeOnObservers:(ExecutionWithObserverBlock)callback {
  DCHECK(callback);
  if (_observers.empty())
    return;
  Iterator it(self);
  id observer;
  while ((observer = it.GetNext()) != nil)
    callback(observer);
}

#pragma mark - Private

- (void)compact {
  DCHECK(!_invocationDepth);
  _observers.erase(std::remove(_observers.begin(), _observers.end(), nil),
                   _observers.end());
}

@end
