/*
 * Copyright 2010 Google Inc.
 *
 * 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.
 */
package com.google.gwt.requestfactory.server;

import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 * Represents one piece in a property reference sequence.
 */
public class RequestProperty implements Iterable<RequestProperty> {

  /**
   * Merge two property chains.
   */
  public static RequestProperty coalesce(RequestProperty... properties) {
    assert properties.length > 0;
    RequestProperty root = new RequestProperty("");
    for (RequestProperty prop : properties) {
      if ("".equals(prop.getPropertyName())) {
        for (RequestProperty p : prop) {
          root.mergeProperty(p);
        }
      } else {
        root.mergeProperty(prop);
      }
    }
    return root;
  }

  public static RequestProperty parse(String selectors) {
    String parts[] = selectors.split("\\s*,\\s*");
    RequestProperty props[] = new RequestProperty[parts.length];
    for (int i = 0; i < parts.length; i++) {
      RequestProperty newProp = new RequestProperty("");
      newProp.parseInternal(parts[i]);
      props[i] = newProp;
    }
    return props.length == 1 ? props[0] : coalesce(props);
  }

  private String propertyName;
  private Map<String, RequestProperty> subProperties;

  private RequestProperty(String propertyName) {
    this.propertyName = propertyName;
  }

  public RequestProperty add(RequestProperty propertyRef) {
    if (subProperties == null) {
      subProperties = new HashMap<String, RequestProperty>();
    }
    subProperties.put(propertyRef.getPropertyName(), propertyRef);
    return this;
  }

  public RequestProperty getProperty(String propName) {
    return subProperties == null ? null : subProperties.get(propName);
  }

  public String getPropertyName() {
    return propertyName;
  }

  public boolean hasProperty(String name) {
    return subProperties == null ? false : subProperties.containsKey(name);
  }

  public Iterator<RequestProperty> iterator() {
    return subProperties == null ? emptyIterator()
        : subProperties.values().iterator();
  }

  public RequestProperty mergeProperty(RequestProperty property) {
    RequestProperty foundProp = getProperty(property.getPropertyName());
    if (foundProp == null && !"".equals(property.getPropertyName())) {
      add(property);
    } else {
      for (RequestProperty p : property) {
        if (foundProp == null) {
          add(p);
        } else {
          foundProp.mergeProperty(p);
        }
      }
    }
    return foundProp;
  }

  @SuppressWarnings({"cast", "unchecked"})
  private Iterator<RequestProperty> emptyIterator() {
    return (Iterator<RequestProperty>) Collections.EMPTY_MAP.values().iterator();
  }

  private RequestProperty getOrCreate(String part) {
    RequestProperty prop = getProperty(part);
    if (prop == null) {
      prop = new RequestProperty(part);
      add(prop);
    }
    return prop;
  }

  private RequestProperty parseInternal(String sequence) {
    int dotIndex = sequence.indexOf('.');
    String part = dotIndex > -1 ? sequence.substring(0, dotIndex) : sequence;
    RequestProperty prop = getOrCreate(part);
    add(prop);

    if (dotIndex > -1) {
      if (dotIndex < sequence.length() - 1) {
        String next = sequence.substring(dotIndex + 1);
        if ("".equals(next)) {
          throw new IllegalArgumentException("Empty property name '..' not allowed in " + sequence);
        }
        if (next.length() > 0) {
          return prop.parseInternal(next);
        }
      }
      throw new IllegalArgumentException("Trailing '.' in with() call " + sequence);
    }
    return prop;
  }
}
