text:
// Generated by the protocol buffer compiler.  DO NOT EDIT!
// source: test.proto

package com.liquidm;

public final class Test {
  private Test() {}
  public static void registerAllExtensions(
      com.google.protobuf.ExtensionRegistry registry) {
  }
  public interface VarietyOrBuilder
      extends com.google.protobuf.MessageOrBuilder {

    // required int32 x = 1;
    /**
     * required int32 x = 1;
     */
    boolean hasX();
    /**
     * required int32 x = 1;
     */
    int getX();

    // required int32 y = 2;
    /**
     * required int32 y = 2;
     */
    boolean hasY();
    /**
     * required int32 y = 2;
     */
    int getY();

    // optional string tag = 3;
    /**
     * optional string tag = 3;
     */
    boolean hasTag();
    /**
     * optional string tag = 3;
     */
    java.lang.String getTag();
    /**
     * optional string tag = 3;
     */
    com.google.protobuf.ByteString
        getTagBytes();
  }
  /**
   * Protobuf type {@code example.liquidm.Variety}
   */
  public static final class Variety extends
      com.google.protobuf.GeneratedMessage
      implements VarietyOrBuilder {
    // Use Variety.newBuilder() to construct.
    private Variety(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private Variety(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final Variety defaultInstance;
    public static Variety getDefaultInstance() {
      return defaultInstance;
    }

    public Variety getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final com.google.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private Variety(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
          com.google.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 8: {
              bitField0_ |= 0x00000001;
              x_ = input.readInt32();
              break;
            }
            case 16: {
              bitField0_ |= 0x00000002;
              y_ = input.readInt32();
              break;
            }
            case 26: {
              bitField0_ |= 0x00000004;
              tag_ = input.readBytes();
              break;
            }
          }
        }
      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new com.google.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return com.liquidm.Test.internal_static_example_liquidm_Variety_descriptor;
    }

    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return com.liquidm.Test.internal_static_example_liquidm_Variety_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              com.liquidm.Test.Variety.class, com.liquidm.Test.Variety.Builder.class);
    }

    public static com.google.protobuf.Parser<Variety> PARSER =
        new com.google.protobuf.AbstractParser<Variety>() {
      public Variety parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        return new Variety(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public com.google.protobuf.Parser<Variety> getParserForType() {
      return PARSER;
    }

    /**
     * Protobuf enum {@code example.liquidm.Variety.Foonum}
     */
    public enum Foonum
        implements com.google.protobuf.ProtocolMessageEnum {
      /**
       * A = 1;
       */
      A(0, 1),
      /**
       * B = 2;
       */
      B(1, 2),
      ;

      /**
       * A = 1;
       */
      public static final int A_VALUE = 1;
      /**
       * B = 2;
       */
      public static final int B_VALUE = 2;

      public final int getNumber() { return value; }

      public static Foonum valueOf(int value) {
        switch (value) {
          case 1: return A;
          case 2: return B;
          default: return null;
        }
      }

      public static com.google.protobuf.Internal.EnumLiteMap<Foonum>
          internalGetValueMap() {
        return internalValueMap;
      }
      private static com.google.protobuf.Internal.EnumLiteMap<Foonum>
          internalValueMap =
            new com.google.protobuf.Internal.EnumLiteMap<Foonum>() {
              public Foonum findValueByNumber(int number) {
                return Foonum.valueOf(number);
              }
            };

      public final com.google.protobuf.Descriptors.EnumValueDescriptor
          getValueDescriptor() {
        return getDescriptor().getValues().get(index);
      }
      public final com.google.protobuf.Descriptors.EnumDescriptor
          getDescriptorForType() {
        return getDescriptor();
      }
      public static final com.google.protobuf.Descriptors.EnumDescriptor
          getDescriptor() {
        return com.liquidm.Test.Variety.getDescriptor().getEnumTypes().get(0);
      }

      private static final Foonum[] VALUES = values();

      public static Foonum valueOf(
          com.google.protobuf.Descriptors.EnumValueDescriptor desc) {
        if (desc.getType() != getDescriptor()) {
          throw new java.lang.IllegalArgumentException(
            "EnumValueDescriptor is not for this type.");
        }
        return VALUES[desc.getIndex()];
      }

      private final int index;
      private final int value;

      private Foonum(int index, int value) {
        this.index = index;
        this.value = value;
      }

      // @@protoc_insertion_point(enum_scope:example.liquidm.Variety.Foonum)
    }

    private int bitField0_;
    // required int32 x = 1;
    public static final int X_FIELD_NUMBER = 1;
    private int x_;
    /**
     * required int32 x = 1;
     */
    public boolean hasX() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * required int32 x = 1;
     */
    public int getX() {
      return x_;
    }

    // required int32 y = 2;
    public static final int Y_FIELD_NUMBER = 2;
    private int y_;
    /**
     * required int32 y = 2;
     */
    public boolean hasY() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * required int32 y = 2;
     */
    public int getY() {
      return y_;
    }

    // optional string tag = 3;
    public static final int TAG_FIELD_NUMBER = 3;
    private java.lang.Object tag_;
    /**
     * optional string tag = 3;
     */
    public boolean hasTag() {
      return ((bitField0_ & 0x00000004) == 0x00000004);
    }
    /**
     * optional string tag = 3;
     */
    public java.lang.String getTag() {
      java.lang.Object ref = tag_;
      if (ref instanceof java.lang.String) {
        return (java.lang.String) ref;
      } else {
        com.google.protobuf.ByteString bs =
            (com.google.protobuf.ByteString) ref;
        java.lang.String s = bs.toStringUtf8();
        if (bs.isValidUtf8()) {
          tag_ = s;
        }
        return s;
      }
    }
    /**
     * optional string tag = 3;
     */
    public com.google.protobuf.ByteString
        getTagBytes() {
      java.lang.Object ref = tag_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b =
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        tag_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    private void initFields() {
      x_ = 0;
      y_ = 0;
      tag_ = "";
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized != -1) return isInitialized == 1;

      if (!hasX()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasY()) {
        memoizedIsInitialized = 0;
        return false;
      }
      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        output.writeInt32(1, x_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeInt32(2, y_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        output.writeBytes(3, getTagBytes());
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(1, x_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(2, y_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBytesSize(3, getTagBytes());
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static com.liquidm.Test.Variety parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static com.liquidm.Test.Variety parseFrom(
        com.google.protobuf.ByteString data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static com.liquidm.Test.Variety parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static com.liquidm.Test.Variety parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static com.liquidm.Test.Variety parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static com.liquidm.Test.Variety parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static com.liquidm.Test.Variety parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static com.liquidm.Test.Variety parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static com.liquidm.Test.Variety parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static com.liquidm.Test.Variety parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(com.liquidm.Test.Variety prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code example.liquidm.Variety}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessage.Builder<Builder>
       implements com.liquidm.Test.VarietyOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return com.liquidm.Test.internal_static_example_liquidm_Variety_descriptor;
      }

      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return com.liquidm.Test.internal_static_example_liquidm_Variety_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                com.liquidm.Test.Variety.class, com.liquidm.Test.Variety.Builder.class);
      }

      // Construct using com.liquidm.Test.Variety.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        x_ = 0;
        bitField0_ = (bitField0_ & ~0x00000001);
        y_ = 0;
        bitField0_ = (bitField0_ & ~0x00000002);
        tag_ = "";
        bitField0_ = (bitField0_ & ~0x00000004);
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return com.liquidm.Test.internal_static_example_liquidm_Variety_descriptor;
      }

      public com.liquidm.Test.Variety getDefaultInstanceForType() {
        return com.liquidm.Test.Variety.getDefaultInstance();
      }

      public com.liquidm.Test.Variety build() {
        com.liquidm.Test.Variety result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public com.liquidm.Test.Variety buildPartial() {
        com.liquidm.Test.Variety result = new com.liquidm.Test.Variety(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        result.x_ = x_;
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        result.y_ = y_;
        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
          to_bitField0_ |= 0x00000004;
        }
        result.tag_ = tag_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof com.liquidm.Test.Variety) {
          return mergeFrom((com.liquidm.Test.Variety)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(com.liquidm.Test.Variety other) {
        if (other == com.liquidm.Test.Variety.getDefaultInstance()) return this;
        if (other.hasX()) {
          setX(other.getX());
        }
        if (other.hasY()) {
          setY(other.getY());
        }
        if (other.hasTag()) {
          bitField0_ |= 0x00000004;
          tag_ = other.tag_;
          onChanged();
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        if (!hasX()) {

          return false;
        }
        if (!hasY()) {

          return false;
        }
        return true;
      }

      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        com.liquidm.Test.Variety parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (com.liquidm.Test.Variety) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      // required int32 x = 1;
      private int x_ ;
      /**
       * required int32 x = 1;
       */
      public boolean hasX() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * required int32 x = 1;
       */
      public int getX() {
        return x_;
      }
      /**
       * required int32 x = 1;
       */
      public Builder setX(int value) {
        bitField0_ |= 0x00000001;
        x_ = value;
        onChanged();
        return this;
      }
      /**
       * required int32 x = 1;
       */
      public Builder clearX() {
        bitField0_ = (bitField0_ & ~0x00000001);
        x_ = 0;
        onChanged();
        return this;
      }

      // required int32 y = 2;
      private int y_ ;
      /**
       * required int32 y = 2;
       */
      public boolean hasY() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * required int32 y = 2;
       */
      public int getY() {
        return y_;
      }
      /**
       * required int32 y = 2;
       */
      public Builder setY(int value) {
        bitField0_ |= 0x00000002;
        y_ = value;
        onChanged();
        return this;
      }
      /**
       * required int32 y = 2;
       */
      public Builder clearY() {
        bitField0_ = (bitField0_ & ~0x00000002);
        y_ = 0;
        onChanged();
        return this;
      }

      // optional string tag = 3;
      private java.lang.Object tag_ = "";
      /**
       * optional string tag = 3;
       */
      public boolean hasTag() {
        return ((bitField0_ & 0x00000004) == 0x00000004);
      }
      /**
       * optional string tag = 3;
       */
      public java.lang.String getTag() {
        java.lang.Object ref = tag_;
        if (!(ref instanceof java.lang.String)) {
          java.lang.String s = ((com.google.protobuf.ByteString) ref)
              .toStringUtf8();
          tag_ = s;
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * optional string tag = 3;
       */
      public com.google.protobuf.ByteString
          getTagBytes() {
        java.lang.Object ref = tag_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b =
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          tag_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * optional string tag = 3;
       */
      public Builder setTag(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000004;
        tag_ = value;
        onChanged();
        return this;
      }
      /**
       * optional string tag = 3;
       */
      public Builder clearTag() {
        bitField0_ = (bitField0_ & ~0x00000004);
        tag_ = getDefaultInstance().getTag();
        onChanged();
        return this;
      }
      /**
       * optional string tag = 3;
       */
      public Builder setTagBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000004;
        tag_ = value;
        onChanged();
        return this;
      }

      // @@protoc_insertion_point(builder_scope:example.liquidm.Variety)
    }

    static {
      defaultInstance = new Variety(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:example.liquidm.Variety)
  }

  private static com.google.protobuf.Descriptors.Descriptor
    internal_static_example_liquidm_Variety_descriptor;
  private static
    com.google.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_example_liquidm_Variety_fieldAccessorTable;

  public static com.google.protobuf.Descriptors.FileDescriptor
      getDescriptor() {
    return descriptor;
  }
  private static com.google.protobuf.Descriptors.FileDescriptor
      descriptor;
  static {
    java.lang.String[] descriptorData = {
      "\n\ntest.proto\022\017example.liquidm\"D\n\007Variety" +
      "\022\t\n\001x\030\001 \002(\005\022\t\n\001y\030\002 \002(\005\022\013\n\003tag\030\003 \001(\t\"\026\n\006F" +
      "oonum\022\005\n\001A\020\001\022\005\n\001B\020\002B\020\n\013com.liquidm\210\001\001"
    };
    com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
      new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
        public com.google.protobuf.ExtensionRegistry assignDescriptors(
            com.google.protobuf.Descriptors.FileDescriptor root) {
          descriptor = root;
          internal_static_example_liquidm_Variety_descriptor =
            getDescriptor().getMessageTypes().get(0);
          internal_static_example_liquidm_Variety_fieldAccessorTable = new
            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
              internal_static_example_liquidm_Variety_descriptor,
              new java.lang.String[] { "X", "Y", "Tag", });
          return null;
        }
      };
    com.google.protobuf.Descriptors.FileDescriptor
      .internalBuildGeneratedFileFrom(descriptorData,
        new com.google.protobuf.Descriptors.FileDescriptor[] {
        }, assigner);
  }

  // @@protoc_insertion_point(outer_class_scope)
}


text:
<?php

class SuiPaymentInterval extends SuiAppModel
{
	var $name = 'SuiPaymentInterval';

	var $displayField = 'internal_code';

	var $hasAndBelongsToMany = array('Sui.SuiSubscription');

	var $validate = array(
		'internal_code' => array(
			'rule' => 'numeric',
			'message' => 'Somente números',
			'allowEmpty' => false
		),
		'code_start' => array(
			'rule' => 'numeric',
			'message' => 'Somente números',
			'allowEmpty' => false
		),
		'code_end' => array(
			'numeric' => array(
				'rule' => 'numeric',
				'message' => 'Somente números',
				'allowEmpty' => false
			),
			'greater' => array(
				'rule' => array('greaterThan', 'code_start'),
				'message' => 'Deve ser maior que o código inicial'
			)
		),
	);

	function greaterThan($check, $thanWho)
	{
		if (empty($this->data[$this->alias][$thanWho]))
			return true;

		$valueToCompare = $this->data[$this->alias][$thanWho];
		foreach ($check as $fieldName => $value)
		{
			if ($valueToCompare >= $value)
				return false;
		}

		return true;
	}

	function getNextPaymentCode($sui_subscription_id, $internal_code = false)
	{
		$this->bindModel(array(
			'hasOne' => array(
				'SuiPaymentIntervalsSuiSubscription' => array(
					'className' => 'Sui.SuiPaymentIntervalsSuiSubscription'
				)
			)
		));

		$contain = array('SuiPaymentIntervalsSuiSubscription');
		$conditions = array(
			'SuiPaymentIntervalsSuiSubscription.sui_subscription_id' => $sui_subscription_id,
			'SuiPaymentInterval.active' => true
		);

		if ($internal_code) {
			$conditions['SuiPaymentInterval.internal_code'] = $internal_code;
		}
		$intervals = $this->find('all', compact('conditions', 'contain'));
		if (!empty($intervals)) {
			$first_interval = $intervals[0];
			$first_interval['SuiPaymentInterval']['offset']++;

			$saved = $this->save(array('SuiPaymentInterval' => array(
				'id' => $first_interval['SuiPaymentInterval']['id'],
				'offset' => $first_interval['SuiPaymentInterval']['offset'],
				'active' => $first_interval['SuiPaymentInterval']['offset'] != $first_interval['SuiPaymentInterval']['code_end']
			)));
			// @todo fire a e-mail telling that the interval is running off.
			if ($saved) {
				return $first_interval;
			}
		}
		return false;
	}
}

redpajama_set_name: RedPajamaGithub


text:
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */

/*  Fluent Bit
 *  ==========
 *  Copyright (C) 2015-2022 The Fluent Bit 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.
 */
#ifndef FLB_IN_HEAD_H
#define FLB_IN_HEAD_H

#include <fluent-bit/flb_config.h>
#include <fluent-bit/flb_input.h>
#include <fluent-bit/flb_utils.h>

#include <msgpack.h>

#define DEFAULT_BUF_SIZE      "256"
#define DEFAULT_INTERVAL_SEC  "1"
#define DEFAULT_INTERVAL_NSEC "0"

struct flb_in_head_config {
    int          coll_fd;
    size_t       buf_size; /* size of buf */
    ssize_t      buf_len;  /* read size */
    char         *buf;     /* read buf */
    flb_sds_t    key;
    int          key_len;

    flb_sds_t    filepath; /* to read */

    int          add_path; /* add path mode */
    size_t       path_len;

    int          lines; /* line num to read */
    int          split_line;

    int          interval_sec;
    int          interval_nsec;
    struct flb_input_instance *ins;
};

extern struct flb_input_plugin in_head_plugin;

#endif /* FLB_IN_HEAD_H */


text:
Welcome to Drunk'N'Gun!

![Screen](ArtSources/screenMockup.PNG)
Game Description:
- An infinity runner game where our hero fights an army of nazis and sees everything in pixel art!

Controls:

- Jump: Space Bar
- Shoot: Z

Tactile controls:

- Jump: Touch Left side of the screen.
- Shoot:Touch Right side of the screen.

Team members:
Adrià Arranz, Cristian Luzón, Jordi Jorba, Robert Font


text:
<?php

namespace ZendTest\Validator\TestAsset;

use Zend\Validator\EmailAddress;

/**
 * @see ZF-12347
 */
class EmailValidatorWithExposedIsReserved extends EmailAddress
{
    public function isReserved($host)
    {
        return parent::isReserved($host);
    }
}


text:
var express = require('express');
var SignalRJS = require('../../../index');
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
var session = require('express-session');
var cookieParser = require('cookie-parser');
var morgan = require('morgan');
var bodyParser = require('body-parser');

var users = [];

function findById(id, cb) {
  if (!users[id])
  	return cb(new Error('User ' + id + ' does not exist'));

	cb(null, users[id]);
};

function findByUserName(userName, cb) {
	console.log(userName);
	if(!userName)
		cb(null,null);

	var userFound = false;
	users.forEach(function(user){
		if(user.userName === userName){
			userFound = true;
			return cb(null,user);
		}
	});
	if(!userFound){
		var newUser = {id:users.length,userName : userName}
		users.push(newUser);
		return cb(null, newUser);
	}
};

passport.serializeUser(function(user, done) {
  done(null, user.id);
});

passport.deserializeUser(function(id, done) {
  findById(id, function (err, user) {
    done(err, user);
  });
});

passport.use(new LocalStrategy(function(userName, password, done) {
    process.nextTick(function () {
      findByUserName(userName, function(err, user) {
        if (err) { return done(err); }
        if (!user) { return done(null, false, { message: 'Unknown user ' + username });}

        return done(null, user);
      })
    });
  }
));

var signalR = SignalRJS();
signalR.hub('chatHub',{
	broadcast : function(fromUserName,message){
		this.clients.all.invoke('broadcast').withArgs([fromUserName,message])
		console.log('broadcasting:'+message);
	},
	privateSend : function(fromUserName,toUserName,message){
		this.clients.user(toUserName).invoke('onPrivateMessage').withArgs([fromUserName,message])
		console.log('privateSend from('+fromUserName+') to('+toUserName+') message:'+message);
	}
});

var server = express();
server.use(morgan('dev'));
server.use(cookieParser());
server.use(bodyParser());
server.use(session({ secret: 'stuff' }));
server.use(passport.initialize());
server.use(passport.session());
//server.use(server.router);
server.use(express.static(__dirname));
server.post('/login',passport.authenticate('local', { failureRedirect: '/index.html'}),
  function(req, res) {
      res.redirect('/chat.html');
});
server.get('/identity',
		function (req, res, next) {
		  if (req.isAuthenticated()){
		  	return next();
		  }
		  res.redirect('/index.html');
		},
		function(req, res) {
			res.writeHead(200, {"Content-Type": "application/json"});
			res.write(JSON.stringify(req.user));
			res.end();
		});
server.use(signalR.createListener())
server.listen(3000);
signalR.on('CONNECTED',function(){
	console.log('connected');
});


text: export { take } from 'rxjs/operators';


text:
from pyflann import *
from numpy import *
from numpy.random import *

dataset = rand(10000, 128)
testset = rand(1000, 128)

flann = FLANN()
# algorithm can be 'linear', 'kmeans', 'kdtree', 'composite', or 'autotuned'
result, dists = flann.nn(dataset, testset, 5, algorithm="kdtree",
                         branching=32, iterations=7, checks=16)
print result, dists


text:
package com.eveningoutpost.dexdrip.Interfaces;

import com.eveningoutpost.dexdrip.Models.User;

import retrofit.Callback;
import retrofit.http.Body;
import retrofit.http.POST;

/**
 * Created by stephenblack on 11/10/14.
 */
public interface UserInterface {

    @POST("/api/v1/sessions/new")
    void authenticate(@Body User user, Callback callback);

}


text:
/*!**********************************************************************************

	\class			ITyActor
	\brief			Actor class to be used within a scene.
	\date			2/08/2011
	\version		0.1
	\author			Leandro Ostera

	Actor class to be used within a Scene class that works with states (TyState)
	and is meant to be an interface with some virtual methods to be overloaded.

************************************************************************************/

#pragma once // might be more suitable to use define checks, but pragma once seems to work fine on almost every compiler

/*
 * Marmalade SDK Header file includes
 */
#include <TySprite.h>
#include <Iw2D.h>
#include <IwGxTypes.h>

/*
 * Standard C++ Header file includes
 */
#include <string>
#include <vector>
#include <iostream>

/*!
 * \enum	TOASTY_ACTOR_STATE
 * \brief	Actor State enumeration
 *	You might provide your own set of states but these (so far) are useful enough.
 */
enum TOASTY_ACTOR_STATE {
		TOASTY_ACTOR_WALKING=0,	/*! Actor is moving */
		TOASTY_ACTOR_ATTACKING, /*! Actor is attacking */
		TOASTY_ACTOR_DEFENDING, /*! Actor is defending */
		TOASTY_ACTOR_STANDING,  /*! Actor is holding position */
		TOASTY_ACTOR_APPEARING, /*! Actor is appearing */
		TOASTY_ACTOR_DYING,		/*! Actor is dying */
		TOASTY_ACTOR_DEAD,		/*! Actor is dead */
		TOASTY_ACTOR_IDLE		/*! Actor is idle */
	};

class ITyActor {

	private:
		/*!
		 * \property	m_ID	Long int used as Actor constant identifier.
		 */
		const int64				m_ID;

		/*!
		 * \property	m_Built	Bool flag telling whether the Actor has been built or not.
		 */
		bool					m_Built;

	protected:
		/*!
		 * \property	m_Name	std::string for the name of the actor.
		 */
		std::string				m_Name;

		/*!
		 * \property	m_Role	std::string for the role of the actor in the scene.
		 */
		std::string				m_Role;

		/*!
		 * \property	m_Depth	Depth of the actor (if ZOrdered is active in an scene, actors will be sorted by depth) as integer (can be negative).
		 */
		int						m_Depth;

		/*!
		 * \property	m_Active	Bool flag that determines whether it should be processed or skipped.
		 */
		bool					m_Active;

		/*!
		 * \property	m_Visible	Bool flag that determines whether the actor should be drawn or not.
		 */
		bool					m_Visible;

		/*!
		 * \property	m_Solid		Bool flag used for collision checking.
		 */
		bool					m_Solid;

		/*!
		 *	\class	TyState
		 *	\brief	Inner class used to relate a Actor State with a Sprite.
		 */
		class TyState {
		public:
			/*!
			 * \property	sprite	TySprite representing the actors state.
			 */
			TySprite*			sprite;

			/*!
			* \property		state	TOASTY_ACTOR_STATE value.
			*/
			TOASTY_ACTOR_STATE	state;

			/*!
			 *	\brief	Constructor
			 *	\param	pSprite	TySprite to associate with pState
			 *	\param	pState	TOASTY_ACTOR_STATE to associate with pSprite
			 *
			 *	Simply inits internal values.
			 */
			TyState( TySprite* pSprite = 0, TOASTY_ACTOR_STATE pState = TOASTY_ACTOR_IDLE): sprite(pSprite), state(pState)
			{
				;
			}
		};

		/*!
		 * \property	m_States	std::vector of TyStates used to contain all the states of the actor
		 */
		std::vector<TyState>	m_States;

		/*!
		 * \property	m_CurrentState	Pointer to the current state.
		 */
		TyState*				m_CurrentState;

		/*!
		 * \property	m_LastState	Pointer to the last state.
		 */
		TyState*				m_LastState;

		/*!
		 * \property	m_Mask	IwRect representing actors collision mask
		 */
		CIwRect					m_Mask;

		/*!
		 * \property	m_Position	IwSVec2 vector representing the (x,y) position of the actor from the scene (0,0). This is, it is a relative value and depends on the scene position on screen.
		 */
		CIwSVec2				m_Position;

		friend class TyScene;

	public:
		/*!
		 *	\brief	Constructor
		 *	\param	pID			Integer value for the Actor ID.
		 *	\param	pActive		Boolean value. True if active, false otherwise.
		 *	\param	pVisible	Boolean value. True if visible, false otherwise.
		 *	\param	pSolid		Boolean value. True if solid, false otherwise.
		 *	\param	pMask		CIwRect(x,y,w,h). Actors collision mask, relative to Actors position.
		 *	\param	pPosition	CIwSVec2(x,y).	Actors position. Relative to Scene position.
		 *
		 *	This is the main constructor. It initializes the following m_rom_erties:
		 *					\arg	\c m_ID			, pID. Remember this is a constant!
		 *					\arg	\c m_Built		, true
		 *					\arg	\c m_Depth		, 0
		 *					\arg	\c m_Active		, true
		 *					\arg	\c m_Visible	, true
		 *					\arg	\c m_Solid		, true
		 *					\arg	\c m_Mask		, CIwRect(0,0,0,0)
		 *					\arg	\c m_Position	, CIwSVec2(0,0)
		 */
		ITyActor(int64 pID, bool pActive = true, bool pVisible = true, bool pSolid = true, CIwRect pMask = CIwRect(0,0,0,0), CIwSVec2 pPosition = CIwSVec2::g_Zero)
			: m_ID(pID), m_Built(true), m_Depth(0), m_Active(pActive), m_Visible(pVisible), m_Solid(pSolid), m_Mask(pMask), m_Position(pPosition)
		{
			;
		}

		/*!
		 *	\brief	Destructor
		 *	It actually does nothing but deleting the states.
		 */
		virtual ~ITyActor(){ ; }

		/*!
		 *	\brief	Is the actor built?
		 *	\returns bool	True if built, false otherwise.
		 */
		bool	IsBuilt()	const	{	return m_Built;		}

		/*!
		 *	\brief	Is the actor active?
		 *	\returns bool	True if active, false otherwise.
		 */
		bool	IsActive()	const	{	return m_Active;	}

		/*!
		 *	\brief	Is the actor visible?
		 *	\returns bool	True if visible, false otherwise.
		 */
		bool	IsVisible() const	{	return m_Visible;	}

		/*!
		 *	\brief	Is the actor solid?
		 *	\returns bool	True if solid, false otherwise.
		 */
		bool	IsSolid()	const	{	return m_Solid;		}

		/*!
		 *	\brief	Adds a new state to the State Vector.
		 *
		 *	\param	pSprite	TySprite sprite to associate with pState.
		 *	\param	pState	TOASTY_ACTOR_STATE state to associate with pSprite.
		 *
		 *	\returns bool	True if added succesfully, false if pState is already associated to a Sprite.
		 *
		 *	It instantiates a new TyState object and pushes it back in the m_State vector if pState is not yet associated to a pSprite in the vector.
		 */
		bool	AddState(TySprite* pSprite, TOASTY_ACTOR_STATE pState);

		/*!
		 *	\brief	Deletes a state from the State Vector.
		 *
		 *	\param	pState	TOASTY_ACTOR_STATE state to delete.
		 *
		 *	\returns bool	True if deleted succesfully, false if pState is not in the vector.
		 *
		 *	Deletes the state pState from m_State if it is there and if it is not the current state.
		 */
		bool	DeleteState(TOASTY_ACTOR_STATE pState);

		/*!
		 *	\brief	Sets a state from the State Vector as current state.
		 *
		 *	\param	pState	TOASTY_ACTOR_STATE state to set as current.
		 *
		 *	\returns bool	True if set succesfully, false such state is not in the State Vector.
		 */
		bool	SetCurrentState(TOASTY_ACTOR_STATE pState);

/*!
		 *	\brief	Will be called once the actor is added to a scene.
		 *	\returns bool
		 */
		virtual bool	OnCreate()											{ return true; }

		/*!
		 *	\brief	Will be called once the actor is removed from a scene.
		 *	\returns bool
		 */
		virtual bool	OnDestroy()											{ return true; }

		/*!
		 *	\brief	Will be called on Keyboard Press event.
		 *	\returns void
		 */
		virtual void	OnKeyPress(s3eKey pKey)								{ ; }

		/*!
		 *	\brief	Will be called on Keyboard Release event.
		 *	\returns void
		 */
		virtual void	OnKeyRelease(s3eKey pKey)							{ ; }

		/*!
		 *	\brief	Will be called if a Key is hold.
		 *	\returns void
		 */
		virtual void	OnKeySustain(s3eKey pKey, int64 pMS)				{ ; }

		/*!
		 *	\brief	Will be called if the Screen is touched.
		 *	\returns void
		 */
		virtual void	OnTouchPress(int pX, int pY )						{ ; }

		/*!
		 *	\brief	Will be called if the Screen is hold.
		 *	\returns void
		 */
		virtual void	OnTouchSustain(int pX, int pY, int64 pMS)			{ ; }

		/*!
		 *	\brief	Will be called if a Screentouch is released.
		 *	\returns void
		 */
		virtual void	OnTouchRelease(int pX, int pY)						{ ; }

		/*!
		 *	\brief	Will be called if the screen is touch and then dragged.
		 *	\returns void
		 */
		virtual void	OnTouchDrag(int pX, int pY, int pRelX, int pRelY)	{ ; }

		/*!
		 *	\brief	Will be called if Actor is about to collide with Scene boundaries.
		 *	\returns void
		 */
		virtual void	OnIntersectBoundaries(CIwRect pBoundaries)			{ ; }

		/*!
		 *	\brief	Will be called First in each step,  if Active.
		 *	\returns void
		 */
		virtual void	OnStepStart()										{ ; }	//first		called method

		/*!
		 *	\brief	Will be called Second in each step,  if Active.
		 *	\returns void
		 */
		virtual void	OnStep()											{ ; }	//second

		/*!
		 *	\brief	Will be called after Rendering in each step, if Active.
		 *	\returns void
		 */
		virtual void	OnStepEnd()											{ ; }	//this one is called after OnRender so if you need to update anything between rendering and OnStepStart, do it here

		/*!
		 *	\brief	Will be called before StepEnd, but at the end of each step, if Visible.
		 *	\returns void
		 */
		virtual void	OnRender()											{ ; }	//this is called before OnStepEnd and after OnStep

		/*!
		 *	\brief	Will be called when two actors collide, if Solid.
		 *	\returns void
		 */
		virtual void	OnCollision(ITyActor const& pActor)					{ ; }

		/*!
		 *	\brief	Accessor for the Actors ID.
		 *	\returns int64	The actors ID.
		 */
		int64				GetID()				const		{	return m_ID;					}

		/*!
		 *	\brief	Accessor for the Actors Name.
		 *	\returns std::string	The actors Name.
		 */
		std::string			GetName()			const		{	return m_Name;					}

		/*!
		 *	\brief	Accessor for the Actors Role.
		 *	\returns std::string	The actors Role.
		 */
		std::string			GetRole()			const		{	return m_Role;					}

		/*!
		 *	\brief	Accessor for the Actors Depth.
		 *	\returns int	The actors Depth.
		 */
		int					GetDepth()			const		{	return m_Depth;					}

		/*!
		 *	\brief	Accessor for the Actors Current State.
		 *	\returns TOASTY_ACTOR_STATE	The actors Current State as TOASTY_ACTOR_STATE.
		 */
		TOASTY_ACTOR_STATE	GetCurrentState()	const		{	return m_CurrentState->state;	}

		/*!
		 *	\brief	Accessor for the Actor Last State.
		 *	\returns TOASTY_ACTOR_STATE	The actors Last State as TOASTY_ACTOR_STATE.
		 */
		TOASTY_ACTOR_STATE	GetLastState()		const		{	return m_LastState->state;		}

		/*!
		 *	\brief	Accessor for the Actors Mask.
		 *	\returns CIwRect	The actors mask as CIwRect.
		 */
		CIwRect				GetMask()			const		{	return m_Mask;					}

		/*!
		 *	\brief	Accessor for the Actors Position.
		 *	\returns CIwSVec2	The actors position as CIwSVec2.
		 */
		CIwSVec2			GetPosition()		const		{	return m_Position;				}

		/*!
		 *	\brief Mutator for the Actors Name
		 *	\param	pName	std::string of the name.
		 */
		void	SetName(std::string pName)					{	m_Name     = pName;			}

		/*!
		 *	\brief Mutator for the Actors Role
		 *	\param	pRole	std::string of the Role.
		 */
		void	SetRole(std::string pRole)					{	m_Role     = pRole;			}

		/*!
		 *	\brief Mutator for the Actors Depth
		 *	\param	pDepth	int for the Depth.
		 */
		void	SetDepth(int pDepth)						{	m_Depth    = pDepth;		}

		/*!
		 *	\brief Mutator for the Actors Active flag.
		 *	\param	pActive	boolean for Active;
		 */
		void	SetActive(bool pActive)						{	m_Active   = pActive;		}

		/*!
		 *	\brief Mutator for the Actors Visible flag.
		 *	\param	pVisible	boolean for Visible;
		 */
		void	SetVisible(bool pVisible)					{	m_Visible  = pVisible;		}

		/*!
		 *	\brief Mutator for the Actors Solid flag.
		 *	\param	pSolid	boolean for Solid;
		 */
		void	SetSolid(bool pSolid)						{	m_Solid    = pSolid;		}

		/*!
		 *	\brief Mutator for the Actors Collision Mask.
		 *	\param	pMask	CIwRect rect for the Collision Mask.
		 */
		void	SetMask(CIwRect pMask)						{	m_Mask	   = pMask;			}

		/*!
		 *	\brief Mutator for the Actors Position.
		 *	\param	pPosition	CIwSVec2 vector for Position.
		 */
		void	SetPosition(CIwSVec2 pPosition)				{	m_Position = pPosition;		}
};

/*!
	\brief	Compares two actors by Depth
	\param	pActor1	An ITyActor derived actor.
	\param	pActor2	Another ITyActor derived actor.
	\returns	bool
	True if first actor has lesser depth than the second one. False otherwise.
*/
inline bool TyActorCompare(ITyActor* pActor1 ,ITyActor* pActor2)
{
	return (pActor1->GetDepth() < pActor2->GetDepth() ) ? true : false;
}


text:
angular.module('todoService', [])

	// super simple service
	// each function returns a promise object
	.factory('Catas', ['$http',function($http) {
		return {
			get : function() {
				return $http.get('/api/catas');
			},
			create : function(todoData) {
				return $http.post('/api/catas', todoData);
			},
			delete : function(id) {
				return $http.delete('/api/catas/' + id);
			}
		}
	}])

	.factory('Contractors', ['$http',function($http) {
		return {
			get : function() {
				return $http.get('/api/contractors');
			},
			create : function(contractorData) {
				return $http.post('/api/contractors', contractorData);
			},
			delete : function(id) {
				return $http.delete('/api/contractors/' + id);
			}
		}
	}]);


text:
from operator import itemgetter
from unittest import TestCase

import pipeline as pl
from marshmallow import fields

class FakeSchema(pl.BaseSchema):
    str = fields.String()
    int = fields.Integer()
    num = fields.Number()
    datetime = fields.DateTime()
    date = fields.Date(dump_to='a_different_name')
    not_there = fields.String(load_only=True)

class TestSchema(TestCase):
    def test_ckan_serialization(self):
        fields = FakeSchema().serialize_to_ckan_fields()
        self.assertListEqual(
            sorted(fields, key=itemgetter('id')),
            [
                {'id': 'a_different_name', 'type': 'date'},
                {'id': 'datetime', 'type': 'timestamp'},
                {'id': 'int', 'type': 'numeric'},
                {'id': 'num', 'type': 'numeric'},
                {'id': 'str', 'type': 'text'}
            ]
        )

    def test_ckan_serialization_caps(self):
        fields = FakeSchema().serialize_to_ckan_fields(capitalize=True)
        self.assertListEqual(
            sorted(fields, key=itemgetter('id')),
            [
                {'id': 'A_DIFFERENT_NAME', 'type': 'date'},
                {'id': 'DATETIME', 'type': 'timestamp'},
                {'id': 'INT', 'type': 'numeric'},
                {'id': 'NUM', 'type': 'numeric'},
                {'id': 'STR', 'type': 'text'}
            ]
        )


text:
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import IpaInput from 'react-ipa-input';

class App extends Component {
    constructor(props) {
        super(props);
        this.state = {
            value: '',
            language: ''
        };
    }

    onSelectChange(event) {
        this.setState({
            language: event.target.value
        });
    }

    onInputChange(value) {
        console.log('oninputchange', value);
        this.setState({
            value: value
        });
    }

    render() {
        const langs = [
            { name: 'All', code: '' },
            { name: 'English', code: 'en' },
            { name: 'French', code: 'fr' },
            { name: 'Spanish', code: 'es' },
            { name: 'German', code: 'de' },
            { name: 'Russian', code: 'ru' },
            { name: 'Japanese', code: 'ja' },
            { name: 'Arabic', code: 'ar' }];

        return (

                Restrict by language:
                <select id="langselect" value={this.state.language} onChange={this.onSelectChange.bind(this)}>
                    {langs.map(lang => {
                        return <option key={lang.code} value={lang.code}>{lang.name}</option>;
                    })}
                </select>

                <IpaInput
                    value={this.state.value}
                    language={this.state.language}
                    onChange={this.onInputChange.bind(this)} />

IpaInput value: {this.state.value}

        );
    }
}

ReactDOM.render(<App />, document.getElementById('app'));


text:
(function () {
    /**
     * streaming kafka module.
     * @example
     * var kafka = require('eclairjs/streaming/kafka');
     * @module eclairjs/streaming/kafka
     */
    module.exports = {
        KafkaUtils: require(EclairJS_Globals.NAMESPACE + '/streaming/kafka/KafkaUtils')
    }

})();


text:
package com.lufs.java.designpattern.visitor.wikipediasample;

public class Car implements CarElement {
    private CarElement[] carElements;

    public Car() {
        this.carElements = new CarElement[]{
                new Wheel("Front left"),
                new Wheel("Front right"),
                new Wheel("Back left"),
                new Wheel("Back right"),
                new Body(),
                new Engine()
        };
    }

    @Override
    public void accept(CarElementVisitor visitor) {
        for (CarElement carElement : carElements) {
            carElement.accept(visitor);
        }
        visitor.visit(this);
    }
}


text:
package org.consumersunion.stories.dashboard.client.application.questionnaire.widget;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;

import javax.inject.Inject;

import org.consumersunion.stories.common.client.event.CollectionChangedEvent;
import org.consumersunion.stories.common.client.event.RedrawEvent;
import org.consumersunion.stories.common.client.service.RpcCollectionServiceAsync;
import org.consumersunion.stories.common.client.service.RpcQuestionnaireServiceAsync;
import org.consumersunion.stories.common.client.service.response.DatumResponse;
import org.consumersunion.stories.common.client.service.response.PagedDataResponse;
import org.consumersunion.stories.common.shared.model.Collection;
import org.consumersunion.stories.common.shared.model.questionnaire.QuestionnaireI15d;
import org.consumersunion.stories.common.shared.place.ParameterTokens;
import org.consumersunion.stories.common.shared.service.datatransferobject.CollectionData;
import org.consumersunion.stories.dashboard.client.AsyncMockStubber;
import org.consumersunion.stories.dashboard.client.BaseTestModule;
import org.consumersunion.stories.dashboard.client.application.collection.CollectionIdsUtil;
import org.consumersunion.stories.dashboard.client.event.ReloadCollectionsEvent;
import org.consumersunion.stories.dashboard.shared.place.NameTokens;
import org.jukito.JukitoRunner;
import org.junit.Test;
import org.junit.runner.RunWith;

import com.google.common.collect.Lists;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.gwtplatform.mvp.client.proxy.PlaceManager;
import com.gwtplatform.mvp.shared.proxy.PlaceRequest;

import static org.assertj.core.api.Assertions.assertThat;
import static org.consumersunion.stories.common.shared.AuthConstants.ROLE_READER;
import static org.mockito.BDDMockito.given;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
import static org.mockito.Matchers.isA;
import static org.mockito.Matchers.same;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;

@RunWith(JukitoRunner.class)
public class ListQuestionnairePresenterTest {
    public static class Module extends BaseTestModule {
        @Override
        protected void configureTest() {
            super.configureTest();

            bindSpy(ListQuestionnairePresenter.class);

            forceMock(CollectionIdsUtil.class);
        }
    }

    private static final int COLLECTION_ID = 9;
    private static final int QUESTIONNAIRE_ID = 10;

    @Inject
    private ListQuestionnairePresenter presenter;
    @Inject
    private ListQuestionnairePresenter.MyView view;
    @Inject
    private RpcQuestionnaireServiceAsync questionnaireService;
    @Inject
    private RpcCollectionServiceAsync collectionService;
    @Inject
    private PlaceManager placeManager;
    @Inject
    private CollectionIdsUtil collectionIdsUtil;

    @Test
    public void initPresenter_withCollection() {
        presenter.initPresenter(new Collection());

        verify(view).init();
    }

    @Test
    public void initPresenter_withSourceQuestionnaires_setsData() {
        ArrayList<QuestionnaireI15d> questionnaires = Lists.newArrayList(new QuestionnaireI15d());

        presenter.initPresenter(new Collection(), questionnaires);

        verify(view).setData(same(questionnaires), eq(0), eq(1));
    }

    @Test
    public void onCollectionChanged_isRelatedCollection_refreshQuestionnaires() {
        CollectionChangedEvent event = mock(CollectionChangedEvent.class);
        Collection collection = new Collection();
        Collection newCollection = new Collection();
        given(event.getCollection()).willReturn(newCollection);
        given(collectionIdsUtil.isRelatedCollection(same(collection), same(newCollection))).willReturn(true);
        presenter.initPresenter(collection);

        presenter.onCollectionChanged(event);

        verify(view).refreshQuestionnaires();
    }

    @Test
    public void onCollectionChanged_isNotRelatedCollection_doesNothing() {
        CollectionChangedEvent event = mock(CollectionChangedEvent.class);
        Collection collection = new Collection();
        Collection newCollection = new Collection();
        given(event.getCollection()).willReturn(newCollection);
        given(collectionIdsUtil.isRelatedCollection(same(collection), same(newCollection))).willReturn(false);
        presenter.initPresenter(collection);

        presenter.onCollectionChanged(event);

        verify(view, never()).refreshQuestionnaires();
    }

    @Test
    public void loadQuestionnaire_setsDataIntoView_onSuccess() {
        int totalCount = 100;
        int length = 8;
        int start = 0;

        PagedDataResponse<QuestionnaireI15d> response = new PagedDataResponse<QuestionnaireI15d>();
        List<QuestionnaireI15d> questionnaires = new ArrayList<QuestionnaireI15d>();
        response.setData(questionnaires);
        response.setTotalCount(totalCount);
        AsyncMockStubber.callHandleSuccessWith(response)
                .when(questionnaireService)
                .getQuestionnaireSummaries(eq(COLLECTION_ID), eq(start), eq(length), any(AsyncCallback.class));
        presenter.initPresenter(new Collection(COLLECTION_ID, 1));

        presenter.loadQuestionnaire(start, length);

        verify(view).setData(same(questionnaires), eq(start), eq(totalCount));
        verify(presenter).fireEvent(isA(RedrawEvent.class));
    }

    @Test
    public void onReloadCollections_sameCollection_reloadsData() {
        ReloadCollectionsEvent event = mock(ReloadCollectionsEvent.class);
        Collection collection = new Collection(COLLECTION_ID, 1);
        given(event.getSourceCollection()).willReturn(collection);
        presenter.initPresenter(collection);

        DatumResponse<CollectionData> response = new DatumResponse<CollectionData>();
        Collection result = new Collection();
        response.setDatum(new CollectionData(result, new HashSet<String>()));
        AsyncMockStubber.callHandleSuccessWith(response)
                .when(collectionService)
                .getCollection(eq(COLLECTION_ID), eq(ROLE_READER), any(AsyncCallback.class));

        presenter.onReloadCollections(event);

        verify(collectionService).getCollection(eq(COLLECTION_ID), eq(ROLE_READER), any(AsyncCallback.class));
        verify(presenter).initPresenter(same(result));
    }

    @Test
    public void onReloadCollections_relatedCollection_reloadsData() {
        ReloadCollectionsEvent event = mock(ReloadCollectionsEvent.class);
        Collection collection = new Collection(COLLECTION_ID, 1);
        given(event.getRelatedCollectionIds()).willReturn(Lists.<Integer>newArrayList(COLLECTION_ID));
        presenter.initPresenter(collection);

        presenter.onReloadCollections(event);

        verify(collectionService).getCollection(eq(COLLECTION_ID), eq(ROLE_READER), any(AsyncCallback.class));
    }

    @Test
    public void questionnaireDetails_revealsDetailPlace() {
        presenter.questionnaireDetails(new QuestionnaireI15d(COLLECTION_ID, 1));

        PlaceRequest placeRequest = new PlaceRequest.Builder()
                .nameToken(NameTokens.collection)
                .with(ParameterTokens.id, String.valueOf(COLLECTION_ID))
                .build();
        verify(placeManager).revealPlace(placeRequest);
    }

    @Test
    public void testRemoveSourceQuestionnaire() {
        Collection collection = new Collection(COLLECTION_ID, 1);
        QuestionnaireI15d source = new QuestionnaireI15d(QUESTIONNAIRE_ID, 1);
        presenter.initPresenter(collection);

        presenter.removeSourceQuestionnaire(source);

        assertThat(collection.getCollectionSources()).doesNotContain(QUESTIONNAIRE_ID);
        verify(collectionService).updateCollection(same(collection), any(AsyncCallback.class));
    }
}