/*
 * Licensed to jclouds, Inc. (jclouds) under one or more
 * contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  jclouds 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.jclouds.vcloud.director.v1_5.domain;

import static com.google.common.base.Objects.equal;

import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlType;

import com.google.common.base.Objects;
import com.google.common.base.Objects.ToStringHelper;

/**
 * Represents vApp creation parameters.
 *
 * <pre>
 * &lt;complexType name="VAppCreationParams" /&gt;
 * </pre>
 *
 * @author grkvlt@apache.org
 */
@XmlType(name = "VAppCreationParamsType")
public class VAppCreationParamsType extends ParamsType {

   public static Builder<?> builder() {
      return new ConcreteBuilder();
   }

   public Builder<?> toBuilder() {
      return builder().fromVAppCreationParamsType(this);
   }

   private static class ConcreteBuilder extends Builder<ConcreteBuilder> {
   }
   
   public static abstract class Builder<B extends Builder<B>> extends ParamsType.Builder<B> {

      private Reference vAppParent;
      private InstantiationParams instantiationParams;
      private Boolean deploy;
      private Boolean powerOn;

      /**
       * @see VAppCreationParamsType#getVAppParent()
       */
      public B vAppParent(Reference vAppParent) {
         this.vAppParent = vAppParent;
         return self();
      }

      /**
       * @see VAppCreationParamsType#getInstantiationParams()
       */
      public B instantiationParams(InstantiationParams instantiationParams) {
         this.instantiationParams = instantiationParams;
         return self();
      }

      /**
       * @see VAppCreationParamsType#isDeploy()
       */
      public B deploy(Boolean deploy) {
         this.deploy = deploy;
         return self();
      }

      /**
       * @see VAppCreationParamsType#isDeploy()
       */
      public B deploy() {
         this.deploy = Boolean.TRUE;
         return self();
      }

      /**
       * @see VAppCreationParamsType#isDeploy()
       */
      public B notDeploy() {
         this.deploy = Boolean.FALSE;
         return self();
      }

      /**
       * @see VAppCreationParamsType#isPowerOn()
       */
      public B powerOn(Boolean powerOn) {
         this.powerOn = powerOn;
         return self();
      }

      /**
       * @see VAppCreationParamsType#isPowerOn()
       */
      public B powerOn() {
         this.powerOn = Boolean.TRUE;
         return self();
      }

      /**
       * @see VAppCreationParamsType#isPowerOn()
       */
      public B notPowerOn() {
         this.powerOn = Boolean.FALSE;
         return self();
      }
      
      public B fromVAppCreationParamsType(VAppCreationParamsType in) {
         return fromParamsType(in).vAppParent(in.getVAppParent()).instantiationParams(in.getInstantiationParams()).deploy(in.isDeploy()).powerOn(in.isPowerOn());
      }
   }

   protected VAppCreationParamsType() {
      // For JAXB and B use
   }

   public VAppCreationParamsType(Builder<?> builder) {
      super(builder);
      this.vAppParent = builder.vAppParent;
      this.instantiationParams = builder.instantiationParams;
      this.deploy = builder.deploy;
      this.powerOn = builder.powerOn;
   }

   @XmlElement(name = "VAppParent")
   protected Reference vAppParent;
   @XmlElement(name = "InstantiationParams")
   protected InstantiationParams instantiationParams;
   @XmlAttribute
   protected Boolean deploy;
   @XmlAttribute
   protected Boolean powerOn;

   /**
    * Gets the value of the vAppParent property.
    */
   public Reference getVAppParent() {
      return vAppParent;
   }

   /**
    * Gets the value of the instantiationParams property.
    */
   public InstantiationParams getInstantiationParams() {
      return instantiationParams;
   }

   /**
    * Gets the value of the deploy property.
    */
   public Boolean isDeploy() {
      return deploy;
   }

   /**
    * Gets the value of the powerOn property.
    */
   public Boolean isPowerOn() {
      return powerOn;
   }

   @Override
   public boolean equals(Object o) {
      if (this == o)
         return true;
      if (o == null || getClass() != o.getClass())
         return false;
      VAppCreationParamsType that = VAppCreationParamsType.class.cast(o);
      return super.equals(that) &&
            equal(vAppParent, that.vAppParent) &&
            equal(instantiationParams, that.instantiationParams) &&
            equal(deploy, that.deploy) &&
            equal(powerOn, that.powerOn);
   }

   @Override
   public int hashCode() {
      return Objects.hashCode(super.hashCode(), vAppParent, instantiationParams, deploy, powerOn);
   }

   @Override
   public ToStringHelper string() {
      return Objects.toStringHelper("")
            .add("vAppParent", vAppParent)
            .add("instantiationParams", instantiationParams)
            .add("deploy", deploy)
            .add("powerOn", powerOn);
   }
}
