/*
 * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
 * agreements. See the NOTICE file distributed with this work for additional information regarding
 * copyright ownership. The ASF licenses this file to you 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.
 */
package org.apache.geode.cache.lucene;

import static org.apache.geode.cache.lucene.test.LuceneTestUtilities.INDEX_NAME;
import static org.apache.geode.cache.lucene.test.LuceneTestUtilities.REGION_NAME;
import static org.junit.Assert.assertEquals;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.concurrent.TimeUnit;

import org.apache.logging.log4j.Logger;
import org.apache.lucene.analysis.core.KeywordAnalyzer;
import org.junit.Test;
import org.junit.experimental.categories.Category;

import org.apache.geode.cache.Region;
import org.apache.geode.cache.RegionShortcut;
import org.apache.geode.cache.lucene.test.Customer;
import org.apache.geode.cache.lucene.test.Page;
import org.apache.geode.cache.lucene.test.Person;
import org.apache.geode.logging.internal.log4j.api.LogService;
import org.apache.geode.pdx.JSONFormatter;
import org.apache.geode.pdx.PdxReader;
import org.apache.geode.pdx.PdxSerializable;
import org.apache.geode.pdx.PdxWriter;
import org.apache.geode.test.junit.categories.LuceneTest;

@Category({LuceneTest.class})
public class NestedObjectSeralizerIntegrationTest extends LuceneIntegrationTest {

  protected static int WAIT_FOR_FLUSH_TIME = 10000;
  protected static final Logger logger = LogService.getLogger();
  LuceneQuery<Integer, Object> query;
  PageableLuceneQueryResults<Integer, Object> results;

  protected CustomerFactory getCustomerFactory() {
    return Customer::new;
  }

  protected static interface CustomerFactory {
    public Customer create(String name, Collection<String> phoneNumbers,
        Collection<Person> contacts,
        Page[] myHomePages);
  }

  protected Region createRegionAndIndex() {
    luceneService.createIndexFactory().setLuceneSerializer(new FlatFormatSerializer())
        .addField("name").addField("phoneNumbers").addField("myHomePages.content")
        .addField("contacts.name").addField("contacts.email", new KeywordAnalyzer())
        .addField("contacts.phoneNumbers").addField("contacts.address")
        .addField("contacts.homepage.content").addField("contacts.homepage.id")
        .addField(LuceneService.REGION_VALUE_FIELD).create(INDEX_NAME, REGION_NAME);

    Region region = createRegion(REGION_NAME, RegionShortcut.PARTITION);
    return region;
  }

  protected Region createRegionAndIndexOnInvalidFields() {
    luceneService.createIndexFactory().setLuceneSerializer(new FlatFormatSerializer())
        .addField("name").addField("contacts").addField("contacts.page")
        .addField("contacts.missing").addField("missing2").create(INDEX_NAME, REGION_NAME);

    Region region = createRegion(REGION_NAME, RegionShortcut.PARTITION);
    return region;
  }

  protected void feedSomeNestedObjects(Region region) throws InterruptedException {
    Person contact1 = new Person("Tommi Jackson", new String[] {"5036330001", "5036330002"}, 1);
    Person contact2 = new Person("Tommi2 Skywalker", new String[] {"5036330003", "5036330004"}, 2);
    HashSet<Person> contacts1 = new HashSet();
    contacts1.add(contact1);
    contacts1.add(contact2);
    Page[] myHomePages1 = new Page[] {new Page(131), new Page(132)};
    ArrayList<String> phoneNumbers = new ArrayList();
    phoneNumbers.add("5035330001");
    phoneNumbers.add("5035330002");
    Customer customer13 =
        getCustomerFactory().create("Tommy Jackson", phoneNumbers, contacts1, myHomePages1);
    region.put("object-13", customer13);

    Person contact3 = new Person("Johnni Jackson", new String[] {"5036330005", "5036330006"}, 3);
    Person contact4 = new Person("Jackson Skywalker", new String[] {"5036330007", "5036330008"}, 4);
    ArrayList<Person> contacts2 = new ArrayList();
    contacts2.add(contact3);
    contacts2.add(contact4);
    phoneNumbers = new ArrayList();
    phoneNumbers.add("5035330003");
    phoneNumbers.add("5035330004");
    Page[] myHomePages2 = new Page[] {new Page(14), new Page(141)};

    Customer customer14 =
        getCustomerFactory().create("Johnny Jackson", phoneNumbers, contacts2, myHomePages2);
    region.put("object-14", customer14);

    Person contact5 = new Person("Johnni Jackson2", new String[] {"5036330009", "5036330010"}, 5);
    Person contact6 =
        new Person("Jackson2 Skywalker", new String[] {"5036330011", "5036330012"}, 6);
    ArrayList<Person> contacts3 = new ArrayList();
    contacts3.add(contact5);
    contacts3.add(contact6);
    phoneNumbers = new ArrayList();
    phoneNumbers.add("5035330005");
    phoneNumbers.add("5035330006");
    Page[] myHomePages3 = new Page[] {new Page(15), new Page(151)};

    Customer customer15 =
        getCustomerFactory().create("Johnny Jackson2", phoneNumbers, contacts3, myHomePages3);
    region.put("object-15", customer15);

    Person contact7 = new Person("Johnni Jackson21", new String[] {"5036330013", "5036330014"}, 7);
    Person contact8 =
        new Person("Jackson21 Skywalker", new String[] {"5036330015", "5036330016"}, 8);
    ArrayList<Person> contacts4 = new ArrayList();
    contacts4.add(contact7);
    contacts4.add(contact8);
    phoneNumbers = new ArrayList();
    phoneNumbers.add("5035330007");
    phoneNumbers.add("5035330008");
    Page[] myHomePages4 = new Page[] {new Page(16), new Page(161)};

    Customer customer16 =
        getCustomerFactory().create("Johnny Jackson21", phoneNumbers, contacts4, myHomePages4);
    region.put("object-16", customer16);

    region.put("key-1", "region value 1");
    region.put("key-2", "region value 2");
    region.put("key-3", "region value 3");
    region.put("key-4", "region value 4");

    luceneService.waitUntilFlushed(INDEX_NAME, REGION_NAME, WAIT_FOR_FLUSH_TIME,
        TimeUnit.MILLISECONDS);
  }

  @Test
  public void queryOnTopLevelObjectCollectionField_AND_BothExist()
      throws InterruptedException, LuceneQueryException {
    Region region = createRegionAndIndex();
    feedSomeNestedObjects(region);

    query = luceneService.createLuceneQueryFactory().create(INDEX_NAME, REGION_NAME, "131 AND 132",
        "myHomePages.content");
    results = query.findPages();
    assertEquals(1, results.size());
    printResults(results);
  }

  @Test
  public void queryOnTopLevelObjectCollectionField_AND_OneExist()
      throws InterruptedException, LuceneQueryException {
    Region region = createRegionAndIndex();
    feedSomeNestedObjects(region);

    query = luceneService.createLuceneQueryFactory().create(INDEX_NAME, REGION_NAME, "131 AND 133",
        "myHomePages.content");
    results = query.findPages();
    assertEquals(0, results.size());
  }

  @Test
  public void queryOnTopLevelObjectCollectionField_OR_OneExist()
      throws InterruptedException, LuceneQueryException {
    Region region = createRegionAndIndex();
    feedSomeNestedObjects(region);

    query = luceneService.createLuceneQueryFactory().create(INDEX_NAME, REGION_NAME, "131 OR 133",
        "myHomePages.content");
    results = query.findPages();
    assertEquals(1, results.size());
    printResults(results);
  }

  @Test
  public void queryOnTopLevelStringCollectionField_AND_BothExist()
      throws InterruptedException, LuceneQueryException {
    Region region = createRegionAndIndex();
    feedSomeNestedObjects(region);

    query = luceneService.createLuceneQueryFactory().create(INDEX_NAME, REGION_NAME,
        "5035330007 AND 5035330008", "phoneNumbers");
    results = query.findPages();
    assertEquals(1, results.size());
    printResults(results);
  }

  @Test
  public void queryOnTopLevelStringCollectionField_AND_OneExist()
      throws InterruptedException, LuceneQueryException {
    Region region = createRegionAndIndex();
    feedSomeNestedObjects(region);
    query = luceneService.createLuceneQueryFactory().create(INDEX_NAME, REGION_NAME,
        "5035330007 AND 5035330009", "phoneNumbers");
    results = query.findPages();
    assertEquals(0, results.size());
  }

  @Test
  public void queryOnTopLevelStringCollectionField_OR_OneExist()
      throws InterruptedException, LuceneQueryException {
    Region region = createRegionAndIndex();
    feedSomeNestedObjects(region);

    query = luceneService.createLuceneQueryFactory().create(INDEX_NAME, REGION_NAME,
        "5035330007 OR 5035330009", "phoneNumbers");
    results = query.findPages();
    assertEquals(1, results.size());
    printResults(results);
  }

  @Test
  public void queryOnContactNameWithExpression() throws InterruptedException, LuceneQueryException {
    Region region = createRegionAndIndex();
    feedSomeNestedObjects(region);

    query = luceneService.createLuceneQueryFactory().create(INDEX_NAME, REGION_NAME,
        "contacts.name:jackson2*", "name");
    results = query.findPages();
    assertEquals(2, results.size());
    printResults(results);
  }

  @Test
  public void queryOnContactNameWithExactMath() throws InterruptedException, LuceneQueryException {
    Region region = createRegionAndIndex();
    feedSomeNestedObjects(region);

    query = luceneService.createLuceneQueryFactory().create(INDEX_NAME, REGION_NAME,
        "\"Johnni Jackson\"", "contacts.name");
    results = query.findPages();
    assertEquals(1, results.size());
    printResults(results);
  }

  @Test
  public void queryOnNameWithWrongValue() throws InterruptedException, LuceneQueryException {
    Region region = createRegionAndIndex();
    feedSomeNestedObjects(region);

    query = luceneService.createLuceneQueryFactory().create(INDEX_NAME, REGION_NAME,
        "\"Johnni Jackson\"", "name");
    results = query.findPages();
    assertEquals(0, results.size());
  }

  @Test
  public void queryOnNameWithExactMatch() throws InterruptedException, LuceneQueryException {
    Region region = createRegionAndIndex();
    feedSomeNestedObjects(region);

    query = luceneService.createLuceneQueryFactory().create(INDEX_NAME, REGION_NAME,
        "\"Johnny Jackson\"", "name");
    results = query.findPages();
    assertEquals(1, results.size());
    printResults(results);
  }

  @Test
  public void queryOnContactEmailWithAnalyzer() throws InterruptedException, LuceneQueryException {
    Region region = createRegionAndIndex();
    feedSomeNestedObjects(region);

    query = luceneService.createLuceneQueryFactory().create(INDEX_NAME, REGION_NAME,
        "Johnni.Jackson2@pivotal.io", "contacts.email");
    results = query.findPages();
    assertEquals(1, results.size());
    printResults(results);
  }

  @Test
  public void queryOnNonExistEmailField() throws InterruptedException, LuceneQueryException {
    Region region = createRegionAndIndex();
    feedSomeNestedObjects(region);

    query = luceneService.createLuceneQueryFactory().create(INDEX_NAME, REGION_NAME,
        "Johnni.Jackson2@pivotal.io", "email");
    results = query.findPages();
    assertEquals(0, results.size());
  }

  @Test
  public void queryOnContactAddressWithStandardAnalyzer()
      throws InterruptedException, LuceneQueryException {
    Region region = createRegionAndIndex();
    feedSomeNestedObjects(region);

    query = luceneService.createLuceneQueryFactory().create(INDEX_NAME, REGION_NAME, "97006",
        "contacts.address");
    results = query.findPages();
    assertEquals(4, results.size());
    printResults(results);
  }

  @Test
  public void queryOnNonExistAddressField() throws InterruptedException, LuceneQueryException {
    Region region = createRegionAndIndex();
    feedSomeNestedObjects(region);

    query = luceneService.createLuceneQueryFactory().create(INDEX_NAME, REGION_NAME, "97006",
        "address");
    results = query.findPages();
    assertEquals(0, results.size());
  }

  @Test
  public void queryOnThreeLayerField() throws InterruptedException, LuceneQueryException {
    Region region = createRegionAndIndex();
    feedSomeNestedObjects(region);

    query = luceneService.createLuceneQueryFactory().create(INDEX_NAME, REGION_NAME,
        "contacts.homepage.content:Hello", "name");
    results = query.findPages();
    printResults(results);
    assertEquals(4, results.size());
  }

  @Test
  public void queryOnThirdLayerFieldDirectlyShouldNotGetResult()
      throws InterruptedException, LuceneQueryException {
    Region region = createRegionAndIndex();
    feedSomeNestedObjects(region);

    query = luceneService.createLuceneQueryFactory().create(INDEX_NAME, REGION_NAME, "Hello",
        "content");
    results = query.findPages();
    printResults(results);
  }

  @Test
  public void queryOnRegionValueField() throws InterruptedException, LuceneQueryException {
    Region region = createRegionAndIndex();
    feedSomeNestedObjects(region);

    query = luceneService.createLuceneQueryFactory().create(INDEX_NAME, REGION_NAME, "region",
        LuceneService.REGION_VALUE_FIELD);
    results = query.findPages();
    printResults(results);
    assertEquals(4, results.size());
  }

  @Test
  public void nonExistFieldsShouldBeIgnored() throws InterruptedException, LuceneQueryException {
    Region region = createRegionAndIndexOnInvalidFields();
    feedSomeNestedObjects(region);

    LuceneQuery query = luceneService.createLuceneQueryFactory().create(INDEX_NAME, REGION_NAME,
        "Jackson2*", "name");
    PageableLuceneQueryResults<Integer, Object> results = query.findPages();
    assertEquals(2, results.size());
    printResults(results);
  }

  @Test
  public void queryOnNotIndexedFieldShouldReturnNothing()
      throws InterruptedException, LuceneQueryException {
    Region region = createRegionAndIndexOnInvalidFields();
    feedSomeNestedObjects(region);

    query = luceneService.createLuceneQueryFactory().create(INDEX_NAME, REGION_NAME,
        "\"Johnni Jackson\"", "contacts.name");
    results = query.findPages();
    assertEquals(0, results.size());
  }

  @Test
  public void queryWithExactMatchWhileIndexOnSomeWrongFields()
      throws InterruptedException, LuceneQueryException {
    Region region = createRegionAndIndexOnInvalidFields();
    feedSomeNestedObjects(region);

    query = luceneService.createLuceneQueryFactory().create(INDEX_NAME, REGION_NAME,
        "\"Johnny Jackson\"", "name");
    results = query.findPages();
    assertEquals(1, results.size());
    printResults(results);
  }

  @Test
  public void queryOnNotIndexedFieldWithAnalyzerShouldReturnNothing()
      throws InterruptedException, LuceneQueryException {
    Region region = createRegionAndIndexOnInvalidFields();
    feedSomeNestedObjects(region);

    query = luceneService.createLuceneQueryFactory().create(INDEX_NAME, REGION_NAME,
        "Johnni.Jackson2@pivotal.io", "contacts.email");
    results = query.findPages();
    assertEquals(0, results.size());
  }

  @Test
  public void queryOnNotIndexedContactAddressFieldShouldReturnNothing()
      throws InterruptedException, LuceneQueryException {
    Region region = createRegionAndIndexOnInvalidFields();
    feedSomeNestedObjects(region);

    query = luceneService.createLuceneQueryFactory().create(INDEX_NAME, REGION_NAME, "97006",
        "contacts.address");
    results = query.findPages();
    assertEquals(0, results.size());
  }

  @Test
  public void queryOnNotIndexedThreeLayerFieldShouldReturnNothing()
      throws InterruptedException, LuceneQueryException {
    Region region = createRegionAndIndexOnInvalidFields();
    feedSomeNestedObjects(region);

    query = luceneService.createLuceneQueryFactory().create(INDEX_NAME, REGION_NAME,
        "contacts.homepage.content:Hello", "name");
    results = query.findPages();
    assertEquals(0, results.size());
  }

  @Test
  public void queryOnNotExistSecondLevelFieldShouldReturnNothing()
      throws InterruptedException, LuceneQueryException {
    Region region = createRegionAndIndexOnInvalidFields();
    feedSomeNestedObjects(region);

    query = luceneService.createLuceneQueryFactory().create(INDEX_NAME, REGION_NAME, "*",
        "contacts.missing");
    results = query.findPages();
    assertEquals(0, results.size());
  }

  @Test
  public void queryOnNotExistTopLevelFieldShouldReturnNothing()
      throws InterruptedException, LuceneQueryException {
    Region region = createRegionAndIndexOnInvalidFields();
    feedSomeNestedObjects(region);

    query =
        luceneService.createLuceneQueryFactory().create(INDEX_NAME, REGION_NAME, "*", "missing2");
    results = query.findPages();
    assertEquals(0, results.size());
  }

  protected void printResults(PageableLuceneQueryResults<Integer, Object> results) {
    if (results.size() > 0) {
      while (results.hasNext()) {
        results.next().stream().forEach(struct -> {
          if (logger.isDebugEnabled()) {
            logger.debug("Result is:" + struct.getValue());
          }
        });
      }
    }
  }

  protected Region createRegionAndIndexForPdxObject() {
    luceneService.createIndexFactory().setLuceneSerializer(new FlatFormatSerializer())
        .addField("ID").addField("description").addField("status").addField("names")
        .addField("position1.country").addField("position1.secId").addField("positions.secId")
        .addField("positions.country").create(INDEX_NAME, REGION_NAME);

    Region region = createRegion(REGION_NAME, RegionShortcut.PARTITION);
    return region;
  }

  protected void feedSomePdxObjects(Region region) throws InterruptedException {
    SimplePortfolioPdx.resetCounter();
    SimplePositionPdx.resetCounter();
    for (int i = 1; i < 10; i++) {
      SimplePortfolioPdx pdx = new SimplePortfolioPdx(i);
      region.put("object-" + i, pdx);
    }

    luceneService.waitUntilFlushed(INDEX_NAME, REGION_NAME, WAIT_FOR_FLUSH_TIME,
        TimeUnit.MILLISECONDS);
  }

  @Test
  public void queryOnTopLevelPdxField() throws InterruptedException, LuceneQueryException {
    Region region = createRegionAndIndexForPdxObject();
    feedSomePdxObjects(region);

    query = luceneService.createLuceneQueryFactory().create(INDEX_NAME, REGION_NAME, "active",
        "status");
    results = query.findPages();
    // even id number: active status; odd id number: inactive status
    assertEquals(4, results.size());
    printResults(results);
  }

  @Test
  public void queryOnTopLevelPdxArrayField() throws InterruptedException, LuceneQueryException {
    Region region = createRegionAndIndexForPdxObject();
    feedSomePdxObjects(region);

    query = luceneService.createLuceneQueryFactory().create(INDEX_NAME, REGION_NAME, "bbb AND ccc",
        "names");
    results = query.findPages();
    // all the entries should be found
    assertEquals(9, results.size());
    printResults(results);
  }

  @Test
  public void queryOnSecondLevelPdxCollectionField()
      throws InterruptedException, LuceneQueryException {
    Region region = createRegionAndIndexForPdxObject();
    feedSomePdxObjects(region);

    query = luceneService.createLuceneQueryFactory().create(INDEX_NAME, REGION_NAME, "NOVL",
        "positions.secId");
    results = query.findPages();
    assertEquals(1, results.size());
    printResults(results);
  }

  @Test
  public void queryOnSecondLevelPdxField() throws InterruptedException, LuceneQueryException {
    Region region = createRegionAndIndexForPdxObject();
    feedSomePdxObjects(region);

    query = luceneService.createLuceneQueryFactory().create(INDEX_NAME, REGION_NAME, "DELL",
        "position1.secId");
    results = query.findPages();
    assertEquals(1, results.size());
    printResults(results);
  }

  @Test
  public void insertAndQueryJSONObject() throws InterruptedException, LuceneQueryException {
    SimplePortfolioPdx.resetCounter();
    SimplePositionPdx.resetCounter();
    Region region = createRegionAndIndexForPdxObject();

    String jsonCustomer = "{" + "\"ID\" : 3," + "\"position1\" : {" + "\"country\" : \"USA\","
        + "\"secId\" : \"DELL\"," + "\"sharesOutstanding\" : 9000.0," + "\"pid\" : 9,"
        + "\"portfolioId\" : 0" + "}," + "\"positions\" : [ {" + "\"country\" : \"USA\","
        + "\"secId\" : \"NOVL\"," + "\"sharesOutstanding\" : 11000.0," + "\"pid\" : 11,"
        + "\"portfolioId\" : 0" + "}," + "{" + "\"country\" : \"USA\"," + "\"secId\" : \"RHAT\","
        + "\"sharesOutstanding\" : 10000.0," + "\"pid\" : 10," + "\"portfolioId\" : 0" + "} ],"
        + "\"status\" : \"inactive\"," + "\"names\" : [ \"aaa\", \"bbb\", \"ccc\", \"ddd\" ],"
        + "\"description\" : \"XXXX\"," + "\"createTime\" : 0" + "}";
    region.put("jsondoc1", JSONFormatter.fromJSON(jsonCustomer));
    luceneService.waitUntilFlushed(INDEX_NAME, REGION_NAME, WAIT_FOR_FLUSH_TIME,
        TimeUnit.MILLISECONDS);
    query = luceneService.createLuceneQueryFactory().create(INDEX_NAME, REGION_NAME, "NOVL",
        "positions.secId");
    results = query.findPages();
    assertEquals(1, results.size());
    printResults(results);
  }

  public static class SimplePortfolioPdx implements Serializable, PdxSerializable {
    private int ID;
    public String description;
    public long createTime;
    public String status;
    public String[] names = {"aaa", "bbb", "ccc", "ddd"};
    public int[] intArr = {2001, 2017};

    public SimplePositionPdx position1;
    public HashSet positions = new HashSet();

    public static int numInstance = 0;

    /*
     * public String getStatus(){ return status;
     */
    public int getID() {
      return ID;
    }

    public long getCreateTime() {
      return this.createTime;
    }

    public void setCreateTime(long time) {
      this.createTime = time;
    }

    public HashSet getPositions() {
      return positions;
    }

    public SimplePositionPdx getP1() {
      return position1;
    }

    public boolean isActive() {
      return status.equals("active");
    }

    public static String secIds[] = {"SUN", "IBM", "YHOO", "GOOG", "MSFT", "AOL", "APPL", "ORCL",
        "SAP", "DELL", "RHAT", "NOVL", "HP"};

    /* public no-arg constructor required for Deserializable */
    public SimplePortfolioPdx() {
      this.numInstance++;
    }

    public SimplePortfolioPdx(int i) {
      this.numInstance++;
      ID = i;
      if (i % 2 == 0) {
        description = "YYYY";
      } else {
        description = "XXXX";
      }
      status = i % 2 == 0 ? "active" : "inactive";
      position1 = new SimplePositionPdx(secIds[SimplePositionPdx.cnt % secIds.length],
          SimplePositionPdx.cnt * 1000);

      positions.add(new SimplePositionPdx(secIds[SimplePositionPdx.cnt % secIds.length],
          SimplePositionPdx.cnt * 1000));
      positions.add(new SimplePositionPdx(secIds[SimplePositionPdx.cnt % secIds.length],
          SimplePositionPdx.cnt * 1000));
    }

    public SimplePortfolioPdx(int i, int j) {
      this(i);
      this.position1.portfolioId = j;
    }

    public static void resetCounter() {
      numInstance = 0;
    }

    private boolean eq(Object o1, Object o2) {
      return o1 == null ? o2 == null : o1.equals(o2);
    }

    @Override
    public boolean equals(Object o) {
      if (!(o instanceof SimplePortfolioPdx)) {
        return false;
      }
      SimplePortfolioPdx p2 = (SimplePortfolioPdx) o;
      return this.ID == p2.getID();
    }

    @Override
    public int hashCode() {
      return this.ID;
    }


    public String toString() {
      String out = "SimplePortfolioPdx [ID=" + ID + " status=" + status + "\n ";
      Iterator iter = positions.iterator();
      while (iter.hasNext()) {
        out += (SimplePositionPdx) (iter.next()) + ", ";
      }
      out += "\n P1:" + position1;
      return out + "\n]";
    }

    /**
     * Getter for property type.S
     *
     * @return Value of property type.
     */
    public boolean boolFunction(String strArg) {
      return "active".equals(strArg);
    }

    public int intFunction(int j) {
      return j;
    }

    public String funcReturnSecId(Object o) {
      return ((SimplePositionPdx) o).getSecId();
    }

    public long longFunction(long j) {
      return j;
    }

    @Override
    public void fromData(PdxReader in) {
      this.ID = in.readInt("ID");
      this.position1 = (SimplePositionPdx) in.readObject("position1");
      this.positions = (HashSet) in.readObject("positions");
      this.status = in.readString("status");
      this.names = in.readStringArray("names");
      this.description = in.readString("description");
      this.createTime = in.readLong("createTime");
      this.intArr = in.readIntArray("intArr");
    }

    @Override
    public void toData(PdxWriter out) {
      out.writeInt("ID", this.ID);
      out.writeObject("position1", this.position1);
      out.writeObject("positions", this.positions);
      out.writeString("status", this.status);
      out.writeStringArray("names", this.names);
      out.writeString("description", this.description);
      out.writeLong("createTime", this.createTime);
      out.writeIntArray("intArr", this.intArr);
      // Identity Field.
      out.markIdentityField("ID");
    }

  }

  public static class SimplePositionPdx implements Serializable, PdxSerializable, Comparable {
    public String secId;
    private String country = "USA";
    private int pid;
    private double sharesOutstanding;
    public int portfolioId = 0;
    public static int cnt = 0;

    public static int numInstance = 0;

    public SimplePositionPdx() {
      this.numInstance++;
    }

    public SimplePositionPdx(String id, double out) {
      secId = id;
      sharesOutstanding = out;
      pid = cnt++;

      this.numInstance++;
    }

    @Override
    public boolean equals(Object o) {
      if (!(o instanceof SimplePositionPdx))
        return false;
      return this.secId.equals(((SimplePositionPdx) o).secId);
    }

    @Override
    public int hashCode() {
      return this.secId.hashCode();
    }

    public String getSecId() {
      return secId;
    }

    public static void resetCounter() {
      cnt = 0;
    }

    public double getSharesOutstanding() {
      return sharesOutstanding;
    }

    public String toString() {
      return "SimplePositionPdx [secId=" + this.secId + " pid=" + this.pid + " out="
          + this.sharesOutstanding + "]";
    }

    @Override
    public void fromData(PdxReader in) {
      this.country = in.readString("country");
      this.secId = in.readString("secId");
      this.sharesOutstanding = in.readDouble("sharesOutstanding");
      this.pid = in.readInt("pid");
      this.portfolioId = in.readInt("portfolioId");
    }

    @Override
    public void toData(PdxWriter out) {
      out.writeString("country", this.country);
      out.writeString("secId", this.secId);
      out.writeDouble("sharesOutstanding", this.sharesOutstanding);
      out.writeInt("pid", this.pid);
      out.writeInt("portfolioId", this.portfolioId);
      // Identity Field.
      out.markIdentityField("secId");
    }


    @Override
    public int compareTo(Object o) {
      if (o == this || ((SimplePositionPdx) o).secId.equals(this.secId)) {
        return 0;
      } else {
        return this.pid < ((SimplePositionPdx) o).pid ? -1 : 1;
      }

    }
  }
}
