package org.eclipse.viatra.query.runtime.runonce.tests;

import java.util.Arrays;
import java.util.List;
import org.eclipse.viatra.examples.library.Library;
import org.eclipse.viatra.query.runtime.api.IPatternMatch;
import org.eclipse.viatra.query.runtime.api.impl.BasePatternMatch;
import org.eclipse.viatra.query.runtime.exception.ViatraQueryException;
import org.eclipse.viatra.query.runtime.runonce.tests.util.RequestCountOfLibraryQuerySpecification;

/**
 * Pattern-specific match representation of the org.eclipse.viatra.query.runtime.runonce.tests.requestCountOfLibrary pattern,
 * to be used in conjunction with {@link RequestCountOfLibraryMatcher}.
 * 
 * <p>Class fields correspond to parameters of the pattern. Fields with value null are considered unassigned.
 * Each instance is a (possibly partial) substitution of pattern parameters,
 * usable to represent a match of the pattern in the result of a query,
 * or to specify the bound (fixed) input parameters when issuing a query.
 * 
 * @see RequestCountOfLibraryMatcher
 * @see RequestCountOfLibraryProcessor
 * 
 */
@SuppressWarnings("all")
public abstract class RequestCountOfLibraryMatch extends BasePatternMatch {
  private Library fLibrary;
  
  private Integer fReqCount;
  
  private static List<String> parameterNames = makeImmutableList("library", "reqCount");
  
  private RequestCountOfLibraryMatch(final Library pLibrary, final Integer pReqCount) {
    this.fLibrary = pLibrary;
    this.fReqCount = pReqCount;
  }
  
  @Override
  public Object get(final String parameterName) {
    if ("library".equals(parameterName)) return this.fLibrary;
    if ("reqCount".equals(parameterName)) return this.fReqCount;
    return null;
  }
  
  public Library getLibrary() {
    return this.fLibrary;
  }
  
  public Integer getReqCount() {
    return this.fReqCount;
  }
  
  @Override
  public boolean set(final String parameterName, final Object newValue) {
    if (!isMutable()) throw new java.lang.UnsupportedOperationException();
    if ("library".equals(parameterName) ) {
    	this.fLibrary = (Library) newValue;
    	return true;
    }
    if ("reqCount".equals(parameterName) ) {
    	this.fReqCount = (Integer) newValue;
    	return true;
    }
    return false;
  }
  
  public void setLibrary(final Library pLibrary) {
    if (!isMutable()) throw new java.lang.UnsupportedOperationException();
    this.fLibrary = pLibrary;
  }
  
  public void setReqCount(final Integer pReqCount) {
    if (!isMutable()) throw new java.lang.UnsupportedOperationException();
    this.fReqCount = pReqCount;
  }
  
  @Override
  public String patternName() {
    return "org.eclipse.viatra.query.runtime.runonce.tests.requestCountOfLibrary";
  }
  
  @Override
  public List<String> parameterNames() {
    return RequestCountOfLibraryMatch.parameterNames;
  }
  
  @Override
  public Object[] toArray() {
    return new Object[]{fLibrary, fReqCount};
  }
  
  @Override
  public RequestCountOfLibraryMatch toImmutable() {
    return isMutable() ? newMatch(fLibrary, fReqCount) : this;
  }
  
  @Override
  public String prettyPrint() {
    StringBuilder result = new StringBuilder();
    result.append("\"library\"=" + prettyPrintValue(fLibrary) + ", ");
    
    result.append("\"reqCount\"=" + prettyPrintValue(fReqCount)
    );
    return result.toString();
  }
  
  @Override
  public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + ((fLibrary == null) ? 0 : fLibrary.hashCode());
    result = prime * result + ((fReqCount == null) ? 0 : fReqCount.hashCode());
    return result;
  }
  
  @Override
  public boolean equals(final Object obj) {
    if (this == obj)
    	return true;
    if (!(obj instanceof RequestCountOfLibraryMatch)) { // this should be infrequent
    	if (obj == null) {
    		return false;
    	}
    	if (!(obj instanceof IPatternMatch)) {
    		return false;
    	}
    	IPatternMatch otherSig  = (IPatternMatch) obj;
    	if (!specification().equals(otherSig.specification()))
    		return false;
    	return Arrays.deepEquals(toArray(), otherSig.toArray());
    }
    RequestCountOfLibraryMatch other = (RequestCountOfLibraryMatch) obj;
    if (fLibrary == null) {if (other.fLibrary != null) return false;}
    else if (!fLibrary.equals(other.fLibrary)) return false;
    if (fReqCount == null) {if (other.fReqCount != null) return false;}
    else if (!fReqCount.equals(other.fReqCount)) return false;
    return true;
  }
  
  @Override
  public RequestCountOfLibraryQuerySpecification specification() {
    try {
    	return RequestCountOfLibraryQuerySpecification.instance();
    } catch (ViatraQueryException ex) {
     	// This cannot happen, as the match object can only be instantiated if the query specification exists
     	throw new IllegalStateException (ex);
    }
  }
  
  /**
   * Returns an empty, mutable match.
   * Fields of the mutable match can be filled to create a partial match, usable as matcher input.
   * 
   * @return the empty match.
   * 
   */
  public static RequestCountOfLibraryMatch newEmptyMatch() {
    return new Mutable(null, null);
  }
  
  /**
   * Returns a mutable (partial) match.
   * Fields of the mutable match can be filled to create a partial match, usable as matcher input.
   * 
   * @param pLibrary the fixed value of pattern parameter library, or null if not bound.
   * @param pReqCount the fixed value of pattern parameter reqCount, or null if not bound.
   * @return the new, mutable (partial) match object.
   * 
   */
  public static RequestCountOfLibraryMatch newMutableMatch(final Library pLibrary, final Integer pReqCount) {
    return new Mutable(pLibrary, pReqCount);
  }
  
  /**
   * Returns a new (partial) match.
   * This can be used e.g. to call the matcher with a partial match.
   * <p>The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object.
   * @param pLibrary the fixed value of pattern parameter library, or null if not bound.
   * @param pReqCount the fixed value of pattern parameter reqCount, or null if not bound.
   * @return the (partial) match object.
   * 
   */
  public static RequestCountOfLibraryMatch newMatch(final Library pLibrary, final Integer pReqCount) {
    return new Immutable(pLibrary, pReqCount);
  }
  
  private static final class Mutable extends RequestCountOfLibraryMatch {
    Mutable(final Library pLibrary, final Integer pReqCount) {
      super(pLibrary, pReqCount);
    }
    
    @Override
    public boolean isMutable() {
      return true;
    }
  }
  
  private static final class Immutable extends RequestCountOfLibraryMatch {
    Immutable(final Library pLibrary, final Integer pReqCount) {
      super(pLibrary, pReqCount);
    }
    
    @Override
    public boolean isMutable() {
      return false;
    }
  }
}
