/*********************************************************************
 * Copyright (c) 2004, 2007 Boeing
 *
 * This program and the accompanying materials are made
 * available under the terms of the Eclipse Public License 2.0
 * which is available at https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     Boeing - initial API and implementation
 **********************************************************************/

package org.eclipse.osee.ote.message.elements;

import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.logging.Level;

import org.eclipse.osee.ote.core.environment.interfaces.ITimeout;
import org.eclipse.osee.ote.message.Message;
import org.eclipse.osee.ote.message.MessageSystemException;
import org.eclipse.osee.ote.message.data.MessageData;
import org.eclipse.osee.ote.message.enums.DataType;

/**
 * @author Ryan D. Brooks
 * @author Andrew M. Finkbeiner
 */
public abstract class Element implements ITimeout {
//   protected final Message msg;
   private final WeakReference<Message> msg;
   protected String elementName;
   private volatile boolean timedOut;
   private final List<Object> elementPath;
   private final String fullName;

   protected final int byteOffset;
   protected int lsb;
   protected final MessageData messageData;
   protected int msb;
   protected final int originalMsb;
   protected final int originalLsb;
   private String elementPathAsString;

   public Element(Message msg, String elementName, MessageData messageData, int byteOffset, int msb, int lsb, int originalMsb, int originalLsb) {
      this.msg = new WeakReference<>(msg);
      this.elementName = elementName;
      this.messageData = messageData;
      this.byteOffset = byteOffset;
      this.lsb = lsb;
      this.msb = msb;
      this.originalLsb = originalLsb;
      this.originalMsb = originalMsb;
      elementPath = new ArrayList<>();
      fullName = (msg != null ? msg.getName() : messageData.getName()) + "." + this.elementName;
   }

   public Element(Message msg, String elementName, MessageData messageData, int bitOffset, int bitLength) {
      this(msg, elementName, messageData, bitOffset / 8, 0, 0, 0, 0);
      this.msb = bitOffset % 8;
      this.lsb = msb + bitLength - 1;
   }

   public Element(Message msg, String elementName, MessageData messageData, int byteOffset, int msb, int lsb) {
      this(msg, elementName, messageData, byteOffset, msb, lsb, msb, lsb);
   }

   public int getMsb() {
      return msb;
   }

   public int getLsb() {
      return lsb;
   }

   public int getByteOffset() {
      return byteOffset;
   }

   public MessageData getMsgData() {
      return messageData;
   }

   public int getBitLength() {
      return Math.abs(getMsb() - getLsb()) + 1;
   }

   public int getStartingBit() {
      return getByteOffset() * 8 + Math.min(getMsb(), getLsb());
   }

   /*
    * protected void set(TestEnvironmentAccessor accessor, long value) { if (accessor != null) {
    * accessor.getLogger().methodCalledOnObject(accessor, this.getFullName(), (new MethodFormatter()).add(value)); }
    * ((MemHolder) current.get()).getMem().s.setLong(value); if (accessor != null) {
    * accessor.getLogger().methodEnded(accessor); } }
    */
   /**
    * @return Returns full name string.
    */
   public String getFullName() {
      return fullName;
   }

   public String getName() {
      return this.elementName;
   }

   public String getDescriptiveName() {
      return this.elementName;
   }

   /**
    * @return Returns the msg.
    */
   public Message getMessage() {
      return msg.get();
   }

   public String getElementName() {
      return elementName;
   }

   @Override
   public boolean isTimedOut() {
      return this.timedOut;
   }

   @Override
   public void setTimeout(boolean timeout) {
      this.timedOut = timeout;
   }

   public DataType getType() {
      return messageData.getPhysicalIoType();
   }

   /**
    * @return Returns the lsb.
    */
   public int getOriginalLsb() {
      return originalLsb;
   }

   /**
    * @return Returns the msb.
    */
   public int getOriginalMsb() {
      return originalMsb;
   }

   private int calculateBitsToShift() {
      int size = lsb - msb + 1;
      return 32 - size;
   }

   private int calculateLongBitsToShift() {
      int size = lsb - msb + 1;
      return 64 - size;
   }

   protected int signExtend(int value) {
      int bitsToShift = calculateBitsToShift();
      return value << bitsToShift >> bitsToShift;
   }

   protected int removeSign(int value) {
      int bitsToShift = calculateBitsToShift();
      return value << bitsToShift >>> bitsToShift;
   }

   protected long removeSign(long value) {
      int bitsToShift = calculateLongBitsToShift();
      return value << bitsToShift >>> bitsToShift;
   }

   /**
    * @return whether this message maps solely to PubSub
    */
   public boolean isNonMappingElement() {
      return false;
   }

   /**
    * Looks for the element matching this elements name inside one of the messages passed
    * 
    * @param messages Those messages mapped to a certain physical type, one of whom contains a mapping to this element
    * @return An element of one of the messages passed with the same name as this element or this element if no match is
    * found.
    */
   @SuppressWarnings("rawtypes")
   public Element findElementInMessages(Collection<? extends Message> messages) {
      for (Message currentMessage : messages) {
         //         System.out.println("SwitchMessages" + currentMessage.getMessageName());
         Element el = currentMessage.getElement(this.getElementPath());
         if (el != null && currentMessage.isValidElement(this, el)) {
            return el;
         }
      }
      return this.getNonMappingElement();
   }
   
   public Element switchMessages(Collection<? extends Message> messages) {
      for (Message currentMessage : messages) {
         //         System.out.println("SwitchMessages" + currentMessage.getMessageName());
         Element el = currentMessage.getElement(this.getElementPath());
         if (el != null && currentMessage.isValidElement(this, el)) {
            return el;
         }
      }
      return this.getNonMappingElement();
   }

   protected void sendMessage() {
      this.getMessage().send();
   }

   /**
    * This method returns a properly formatted string that describes the range and inclusive/exclusive properties of
    * each end of the range.
    * 
    * @param minValue The minimum value of the range.
    * @param minInclusive If the minumum value of the range is inclusive. If true the actual value must not < and not =
    * to the range value.
    * @param maxValue The maximum value of the range.
    * @param maxInclusive If the maximum value of the range is inclusive. If true the actual value must not > and not =
    * to the range value.
    * @return the string holding "[", "]", "(", or ")"
    */
   protected static String expectedRangeString(Object minValue, boolean minInclusive, Object maxValue, boolean maxInclusive) {
      // A means for a return value
      String retVal;

      // Start with the proper symbol for the lower bound
      if (minInclusive) {
         retVal = "[";
      } else {
         retVal = "(";
      }

      // Add in the minimum and maximum values
      retVal += minValue + " .. " + maxValue;

      // End with the proper symbol for the upper bound
      if (maxInclusive) {
         retVal += "]";
      } else {
         retVal += ")";
      }

      // Return the formatted string
      return retVal;
   }

   protected abstract Element getNonMappingElement();

   protected void throwNoMappingElementException() {
      throw new MessageSystemException(
         "The element " + msg.get().getName() + "." + elementName + " does not exist for the message's current MemType="+msg.get().getMemType()+"!! " + "\nIt shouldn't be used for this environment type!!",
         Level.SEVERE);
   }

   /**
    * @return the elementPath
    */
   public List<Object> getElementPath() {
      return elementPath;
   }

   public void addPath(Object... objs) {
      for (Object obj : objs) {
         elementPath.add(obj);
      }
      elementPath.add(this.getName());
   }

   @Override
   public String toString() {

      return elementName;
   }

   /**
    * Zeroize the data for this element (not the mask).
    */
   public void zeroize() {

      getMsgData().getMem().setLong(0L, byteOffset, msb, lsb);

   }

   public void visit(IElementVisitor visitor) {
      visitor.asGenericElement(this);
   }

   public String getElementPathAsString() {
      if (elementPathAsString == null) {
         StringBuilder sb = new StringBuilder();
         for (int i = 1; i < elementPath.size(); i++) {
            Object obj = elementPath.get(i);
            if (obj instanceof String) {
               sb.append(obj);

            } else if (obj instanceof Integer) {
               sb.delete(sb.length() - 1, sb.length());
               sb.append("[");
               sb.append(((Integer) obj).intValue());
               sb.append("]");
            }
            if (i < elementPath.size() - 1) {
               sb.append(".");
            }
         }
         elementPathAsString = sb.toString();
      }
      return elementPathAsString;
   }

}