code: /*
   * Copyright (c) 2019 the Eclipse Milo Authors
   *
   * 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
   */
  
  package org.eclipse.milo.opcua.stack.core.types.builtin;
  
  import java.util.Objects;
  
  import org.jetbrains.annotations.Nullable;
  
  /**
   * Vendor-specific diagnostic information
   */
  public final class DiagnosticInfo {
  
      public static final DiagnosticInfo NULL_VALUE = new DiagnosticInfo(-1, -1, -1, -1, null, null, null);
  
      /**
       * The symbolicId is defined within the context of a namespace. This namespace is represented as a string and is
       * conveyed to the Client in the stringTable parameter of the ResponseHeader parameter defined in 7.27. The
       * namespaceUri parameter contains the index into the stringTable for this string. -1 indicates that no string is
       * specified.
       * <p>
       * The namespaceUri shall not be the standard OPC UA namespace. There are no symbolicIds provided for
       * standard StatusCodes.
       */
      private final int namespaceUri;
  
      /**
       * The symbolicId shall be used to identify a vendor-specific error or condition; typically the result of some
       * server internal operation. The maximum length of this string is 32 characters. Servers wishing to return a
       * numeric return code should convert the return code into a string and use this string as symbolicId
       * (e.g., "0xC0040007" or "-4").
       * <p>
       * This symbolic identifier string is conveyed to the Client in the stringTable
       * parameter of the ResponseHeader parameter defined in 7.27. The symbolicId parameter contains the index into the
       * stringTable for this string. -1 indicates that no string is specified.
       * <p>
       * The symbolicId shall not contain StatusCodes. If the localizedText contains a translation for the description of
       * a StatusCode, the symbolicId is -1.
       */
      private final int symbolicId;
  
      /**
       * The locale part of the vendor-specific localized text describing the symbolic id.
       * <p>
       * This localized text string is conveyed to the Client in the stringTable parameter of the ResponseHeader parameter
       * defined in 7.27. The localizedText parameter contains the index into the stringTable for this string. -1
       * indicates that no string is specified.
       */
      private final int locale;
  
      /**
       * A vendor-specific localized text string describes the symbolic id. The maximum length of this text string is
       * 256 characters.
       * <p>
       * This localized text string is conveyed to the Client in the stringTable parameter of the ResponseHeader
       * parameter defined in 7.27. The localizedTextIndex parameter contains the index into the stringTable for this
       * string. -1 indicates that no string is specified.
       * <p>
       * The localizedText refers to the symbolicId if present or the string that describes the standard StatusCode if
       * the server provides translations. If the index is -1, the server has no translation to return and the client
       * should use the invariant StatusCode description from the specification.
       */
      private final int localizedText;
  
      /**
       * Vendor-specific diagnostic information.
       */
      private final String additionalInfo;
  
      /**
       * The StatusCode from the inner operation.
       * <p>
       * Many applications will make calls into underlying systems during OPC UA request processing. An OPC UA Server has
       * the option of reporting the status from the underlying system in the diagnostic info.
       */
      private final StatusCode innerStatusCode;
  
      /**
       * The diagnostic info associated with the inner StatusCode.
       */
      private final DiagnosticInfo innerDiagnosticInfo;
  
      public DiagnosticInfo(int namespaceUri,
                            int symbolicId,
                            int locale,
                            int localizedText,
                            @Nullable String additionalInfo,
                            @Nullable StatusCode innerStatusCode,
                            @Nullable DiagnosticInfo innerDiagnosticInfo) {
  
          this.namespaceUri = namespaceUri;
          this.symbolicId = symbolicId;
          this.locale = locale;
          this.localizedText = localizedText;
          this.additionalInfo = additionalInfo;
          this.innerStatusCode = innerStatusCode;
          this.innerDiagnosticInfo = innerDiagnosticInfo;
      }
  
      public int getNamespaceUri() {
          return namespaceUri;
      }
  
      public int getSymbolicId() {
          return symbolicId;
      }
  
      public int getLocale() {
          return locale;
      }
  
      public int getLocalizedText() {
          return localizedText;
      }
  
      public String getAdditionalInfo() {
          return additionalInfo;
      }
  
      public StatusCode getInnerStatusCode() {
          return innerStatusCode;
      }
  
      public DiagnosticInfo getInnerDiagnosticInfo() {
          return innerDiagnosticInfo;
      }
  
      @Override
      public boolean equals(Object o) {
          if (this == o) return true;
          if (o == null || getClass() != o.getClass()) return false;
  
          DiagnosticInfo that = (DiagnosticInfo) o;
  
          return Objects.equals(symbolicId, that.symbolicId) &&
              Objects.equals(namespaceUri, that.namespaceUri) &&
              Objects.equals(localizedText, that.localizedText) &&
              Objects.equals(locale, that.locale) &&
              Objects.equals(additionalInfo, that.additionalInfo) &&
              Objects.equals(innerStatusCode, that.innerStatusCode) &&
              Objects.equals(innerDiagnosticInfo, that.innerDiagnosticInfo);
      }
  
      @Override
      public int hashCode() {
          int result = namespaceUri;
          result = 31 * result + symbolicId;
          result = 31 * result + locale;
          result = 31 * result + localizedText;
          result = 31 * result + (additionalInfo != null ? additionalInfo.hashCode() : 0);
          result = 31 * result + (innerStatusCode != null ? innerStatusCode.hashCode() : 0);
          result = 31 * result + (innerDiagnosticInfo != null ? innerDiagnosticInfo.hashCode() : 0);
          return result;
      }
  
  }
  