library mustache_context;

import 'dart:collection';

import '../lib/src/mirrors.dart';

const String DOT = '\.';

typedef NoParamLambda();
typedef OptionalParamLambda({nestedContext});
typedef TwoParamLambda(String s, {nestedContext});

abstract class MustacheContext {
  factory MustacheContext(ctx,
      {MustacheContext parent, assumeNullNonExistingProperty: true}) {
    return _createMustacheContext(ctx,
        parent: parent,
        assumeNullNonExistingProperty: assumeNullNonExistingProperty);
  }

  get ctx;

  value([arg]);

  bool get isFalsey;

  bool get isLambda;

  MustacheContext field(String key);

  MustacheContext _getMustacheContext(String key);
}

_createMustacheContext(obj,
    {MustacheContext parent, bool assumeNullNonExistingProperty}) {
  if (obj is Iterable) {
    return new _IterableMustacheContextDecorator(obj,
        parent: parent,
        assumeNullNonExistingProperty: assumeNullNonExistingProperty);
  }
  if (obj == false) {
    return falseyContext;
  }
  return new _MustacheContext(obj,
      parent: parent,
      assumeNullNonExistingProperty: assumeNullNonExistingProperty);
}

final falseyContext = new _MustacheContext(false);

class _MustacheContext implements MustacheContext {
  final ctx;
  final _MustacheContext parent;
  final bool assumeNullNonExistingProperty;
  Reflection _ctxReflection;

  _MustacheContext(this.ctx,
      {_MustacheContext this.parent, this.assumeNullNonExistingProperty});

  bool get isLambda => ctx is Function;

  bool get isFalsey => ctx == null || ctx == false;

  value([arg]) => isLambda ? callLambda(arg) : ctx.toString();

  callLambda(arg) {
    if (ctx is NoParamLambda) {
      return ctx is OptionalParamLambda ? ctx(nestedContext: this) : ctx();
    }
    if (ctx is TwoParamLambda) {
      return ctx(arg, nestedContext: this);
    }
    return ctx(arg);
  }

  MustacheContext field(String key) {
    if (ctx == null) return null;
    return _getInThisOrParent(key);
  }

  MustacheContext _getInThisOrParent(String key) {
    var result = _getContextForKey(key);
    //if the result is null, try the parent context

    if (result == null) {
      final hasSlot = ctxReflector.field(key).exists;
      if (!assumeNullNonExistingProperty && !hasSlot && parent == null) {
        throw new StateError('Could not find "$key" in given context');
      }

      //if the result is null, try the parent context
      if (!hasSlot && parent != null) {
        result = parent.field(key);
        if (result != null) {
          return _createChildMustacheContext(result.ctx);
        }
      }
    }
    return result;
  }

  MustacheContext _getContextForKey(String key) {
    if (key == DOT) {
      return this;
    }
    if (key.contains(DOT)) {
      final Iterator<String> i = key.split(DOT).iterator;
      MustacheContext val = this;
      while (i.moveNext()) {
        val = val._getMustacheContext(i.current);
        if (val == null) {
          return null;
        }
      }
      return val;
    }
    //else
    return _getMustacheContext(key);
  }

  MustacheContext _getMustacheContext(String fieldName) {
    final v = ctxReflector.field(fieldName).val();
    return _createChildMustacheContext(v);
  }

  _createChildMustacheContext(obj) {
    if (obj == null) {
      return null;
    }
    return _createMustacheContext(obj,
        parent: this,
        assumeNullNonExistingProperty: this.assumeNullNonExistingProperty);
  }

  Reflection get ctxReflector {
    if (_ctxReflection == null) {
      _ctxReflection = reflect(ctx);
    }
    return _ctxReflection;
  }
}

class _IterableMustacheContextDecorator extends IterableBase<_MustacheContext>
    implements MustacheContext {
  final Iterable ctx;
  final _MustacheContext parent;
  final bool assumeNullNonExistingProperty;

  _IterableMustacheContextDecorator(this.ctx,
      {this.parent, this.assumeNullNonExistingProperty});

  value([arg]) =>
      throw new Exception('Iterable can not be called as a function');

  Iterator<_MustacheContext> get iterator =>
      new _MustacheContextIteratorDecorator(ctx.iterator,
          parent: parent,
          assumeNullNonExistingProperty: assumeNullNonExistingProperty);

  int get length => ctx.length;

  bool get isEmpty => ctx.isEmpty;

  bool get isFalsey => isEmpty;

  bool get isLambda => false;

  field(String key) {
    assert(key ==
        DOT); // 'Iterable can only be iterated. No [] implementation is available'
    return this;
  }

  _getMustacheContext(String key) {
    // 'Iterable can only be asked for empty or isEmpty keys or be iterated'
    assert(key == 'empty' || key == 'isEmpty');
    return new _MustacheContext(isEmpty,
        parent: parent,
        assumeNullNonExistingProperty: assumeNullNonExistingProperty);
  }
}

class _MustacheContextIteratorDecorator extends Iterator<_MustacheContext> {
  final Iterator delegate;
  final _MustacheContext parent;
  final bool assumeNullNonExistingProperty;

  _MustacheContext current;

  _MustacheContextIteratorDecorator(this.delegate,
      {this.parent, this.assumeNullNonExistingProperty});

  bool moveNext() {
    if (delegate.moveNext()) {
      current = new _MustacheContext(delegate.current,
          parent: parent,
          assumeNullNonExistingProperty: assumeNullNonExistingProperty);
      return true;
    } else {
      current = null;
      return false;
    }
  }
}
