package com.capgemini.reports.reports.parameters;

import com.capgemini.framework.teamcenter.authent.TcSession;
import com.capgemini.framework.teamcenter.queries.saved.modelobject.ItemQuery;
import com.capgemini.reports.exceptions.NotFoundException;
import com.teamcenter.soa.client.model.strong.Item;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;

import java.io.Serializable;
import java.util.List;

/**
 * This class gathers information about a product (+unit), and optionally a generic or a generic assemb.<br>
 * This class allows either: <br>
 * <ul>
 * <li>A product and its unit</li>
 * <li>A product, its unit, and a Generic that exists under this product</li>
 * <li>A product, its unit, and a GenericAssemb that exists under this product</li>
 * </ul>
 */
@Slf4j
@Getter
@EqualsAndHashCode
public class SuperModel implements Serializable {

     private static final long serialVersionUID = 2362411651537951479L;
     private static final String GENERIC_BOM = "GenericBom";
     private static final String ASSEMBLY_BOM = "AssemblyBom";
     private static final String TECHNICAL_BOM = "TechnicalBom";
     private final String supermodel;
     private final String revision;
     private final ProductUnit productUnit;


     /**
      * Constructs a {@link SuperModel}.
      *
      * @param productUnit     a {@link ProductUnit} (mandatory)
      * @param supermodel       (mandatory)
      */
     public SuperModel(final ProductUnit productUnit, final String supermodel) {
          super();
          this.productUnit = productUnit;
          this.supermodel = supermodel;
          // The parameter revision is not used via this constructor.
          this.revision = null;
     }

     /**
      * Constructs a {@link SuperModel} Revision.
      *
      * @param productUnit     a {@link ProductUnit} (mandatory)
      * @param supermodel       (may be null)
      * @param revision (may be null) the revision of the Supermodel
      */
     public SuperModel(final ProductUnit productUnit, final String supermodel, final String revision) {
          super();
          this.productUnit = productUnit;
          this.supermodel = supermodel;
          this.revision = revision;
     }

     /**
      * Returns the corresponding Teamcenter {@link Item} (a product, Generic or Generic Assemb).
      *
      * @param session the {@link TcSession} to perform the query.
      * @return the {@link Item} representing the item.
      * @throws NotFoundException if no reults were found
      */
     public Item getItem(final TcSession session) throws NotFoundException {
          ItemQuery savedQuery = new ItemQuery(session);
          savedQuery.searchID(supermodel);
          List<Item> results = savedQuery.findAll();
          if (results == null || results.isEmpty()) {
               throw new NotFoundException("No Super Model found with the provided ID");
          }
          return results.get(0);
     }

     /**
      * Represents a Product-Unit, and some optional Generic or GenericAssemb under it.
      */
     @Getter
     public enum GenericType {
          /**
           * Represents only a product-unit. Follows a BomView named "<b>TechnicalBom</b>".
           */
          ONLY_PRODUCT(TECHNICAL_BOM),
          /**
           * Represents a product-unit and a generic under it. Follows a BomView named "<b>GenericBOM</b>".
           */
          GENERIC(GENERIC_BOM),
          /**
           * Represents a product-unit and a genericAssemb under it. Follows a BomView named "<b>AssemblyBOM</b>".
           */
          GENERIC_ASSEMB(ASSEMBLY_BOM);

          private final String bomLinkType;

          GenericType(final String bomLinkType) {
               this.bomLinkType = bomLinkType;
          }
     }


     /**
      * Returns the corresponding item ID (of the product, Generic or Generic Assemb).
      *
      * @return the item ID
      */
     public String getID() {
          return supermodel;
     }
}
