/*
 * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
 * agreements. See the NOTICE file distributed with this work for additional information regarding
 * copyright ownership. The ASF 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.apache.geode.cache.client.internal.locator;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.apache.geode.internal.GemFireVersion;
import org.apache.geode.internal.lang.ObjectUtils;
import org.apache.geode.internal.lang.StringUtils;
import org.apache.geode.internal.process.PidUnavailableException;
import org.apache.geode.internal.process.ProcessUtils;
import org.apache.geode.internal.serialization.DataSerializableFixedID;
import org.apache.geode.internal.serialization.DeserializationContext;
import org.apache.geode.internal.serialization.SerializationContext;
import org.apache.geode.internal.util.ArgumentRedactor;

/**
 * The LocatorStatusResponse class...
 * </p>
 *
 * @see org.apache.geode.cache.client.internal.locator.ServerLocationResponse
 * @since GemFire 7.0
 */
public class LocatorStatusResponse extends ServerLocationResponse {

  private Integer pid;

  private List<String> jvmArgs;

  private Long uptime;

  private String classpath;
  private String gemfireVersion;
  private String javaVersion;
  private String workingDirectory;

  private String logFile;
  private String host;
  private Integer port;
  private String name;

  private static Integer identifyPid() {
    try {
      return ProcessUtils.identifyPid();
    } catch (PidUnavailableException ignore) {
      return null;
    }
  }

  public LocatorStatusResponse initialize(final int locatorPort, final String locatorHost,
      final String locatorLogFile, final String locatorName) {
    final RuntimeMXBean runtimeBean = ManagementFactory.getRuntimeMXBean();
    this.pid = identifyPid();
    this.jvmArgs = ArgumentRedactor.redactEachInList(runtimeBean.getInputArguments());
    this.uptime = runtimeBean.getUptime();
    this.classpath = runtimeBean.getClassPath();
    this.gemfireVersion = GemFireVersion.getGemFireVersion();
    this.javaVersion = System.getProperty("java.version");
    this.workingDirectory = System.getProperty("user.dir");
    this.logFile = locatorLogFile;
    this.host = locatorHost;
    this.port = locatorPort;
    this.name = locatorName;
    return this;
  }

  @Override
  public int getDSFID() {
    return DataSerializableFixedID.LOCATOR_STATUS_RESPONSE;
  }

  public String getClasspath() {
    return classpath;
  }

  public String getGemFireVersion() {
    return gemfireVersion;
  }

  public String getJavaVersion() {
    return javaVersion;
  }

  @SuppressWarnings("unchecked")
  public List<String> getJvmArgs() {
    return Collections.unmodifiableList(jvmArgs != null ? jvmArgs : Collections.emptyList());
  }

  public Integer getPid() {
    return pid;
  }

  public Long getUptime() {
    return uptime;
  }

  public String getWorkingDirectory() {
    return workingDirectory;
  }

  public String getLogFile() {
    return this.logFile;
  }

  public String getHost() {
    return this.host;
  }

  public Integer getPort() {
    return this.port;
  }

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

  @Override
  public boolean hasResult() {
    return true;
  }

  @Override
  public void fromData(final DataInput in,
      DeserializationContext context) throws IOException, ClassNotFoundException {
    readPid(in);
    readUptime(in);
    readWorkingDirectory(in);
    readJvmArguments(in);
    readClasspath(in);
    readGemFireVersion(in);
    readJavaVersion(in);
    readLogFile(in);
    readHost(in);
    readPort(in);
    readName(in);
  }

  protected void readPid(final DataInput in) throws IOException {
    final int pid = in.readInt();
    this.pid = (pid == 0 ? null : pid);
  }

  protected void readUptime(final DataInput in) throws IOException {
    this.uptime = in.readLong();
  }

  protected void readWorkingDirectory(final DataInput in) throws IOException {
    this.workingDirectory = StringUtils.nullifyIfBlank(in.readUTF());
  }

  protected void readJvmArguments(final DataInput in) throws IOException {
    final int length = in.readInt();
    final List<String> jvmArgs = new ArrayList<>(length);
    for (int index = 0; index < length; index++) {
      jvmArgs.add(in.readUTF());
    }
    this.jvmArgs = jvmArgs;
  }

  protected void readClasspath(final DataInput in) throws IOException {
    this.classpath = StringUtils.nullifyIfBlank(in.readUTF());
  }

  protected void readGemFireVersion(final DataInput in) throws IOException {
    this.gemfireVersion = StringUtils.nullifyIfBlank(in.readUTF());
  }

  protected void readJavaVersion(final DataInput in) throws IOException {
    this.javaVersion = StringUtils.nullifyIfBlank(in.readUTF());
  }

  protected void readLogFile(final DataInput in) throws IOException {
    this.logFile = StringUtils.nullifyIfBlank(in.readUTF());
  }

  protected void readHost(final DataInput in) throws IOException {
    this.host = StringUtils.nullifyIfBlank(in.readUTF());
  }

  protected void readPort(final DataInput in) throws IOException {
    final int port = in.readInt();
    this.port = (port == 0 ? null : port);
  }

  protected void readName(final DataInput in) throws IOException {
    this.name = StringUtils.nullifyIfBlank(in.readUTF());
  }

  @Override
  public void toData(final DataOutput out,
      SerializationContext context) throws IOException {
    writePid(out);
    writeUptime(out);
    writeWorkingDirectory(out);
    writeJvmArguments(out);
    writeClasspath(out);
    writeGemFireVersion(out);
    writeJavaVersion(out);
    writeLogFile(out);
    writeHost(out);
    writePort(out);
    writeName(out);
  }

  protected void writePid(final DataOutput out) throws IOException {
    Integer pid = getPid();
    out.writeInt(pid != null ? pid : (Integer) 0);
  }

  protected void writeUptime(final DataOutput out) throws IOException {
    out.writeLong(getUptime());
  }

  protected void writeWorkingDirectory(final DataOutput out) throws IOException {
    String workingDir = getWorkingDirectory();
    out.writeUTF(workingDir != null ? workingDir : "");
  }

  protected void writeJvmArguments(final DataOutput out) throws IOException {
    final List<String> jvmArgs = getJvmArgs();
    out.writeInt(jvmArgs.size());
    for (final String jvmArg : jvmArgs) {
      out.writeUTF(jvmArg);
    }
  }

  protected void writeClasspath(final DataOutput out) throws IOException {
    String classpath = getClasspath();
    out.writeUTF(classpath != null ? classpath : "");
  }

  protected void writeGemFireVersion(final DataOutput out) throws IOException {
    String version = getGemFireVersion();
    out.writeUTF(version != null ? version : "");
  }

  protected void writeJavaVersion(final DataOutput out) throws IOException {
    String version = getJavaVersion();
    out.writeUTF(version != null ? version : "");
  }

  protected void writeLogFile(final DataOutput out) throws IOException {
    String log = getLogFile();
    out.writeUTF(log != null ? log : "");
  }

  protected void writeHost(final DataOutput out) throws IOException {
    String host = getHost();
    out.writeUTF(host != null ? host : "");
  }

  protected void writePort(final DataOutput out) throws IOException {
    Integer port = getPort();
    out.writeInt(port != null ? port : (Integer) 0);
  }

  protected void writeName(final DataOutput out) throws IOException {
    String name = getName();
    out.writeUTF(name != null ? name : "");
  }

  @Override
  public boolean equals(final Object obj) {
    if (obj == this) {
      return true;
    }

    if (!(obj instanceof LocatorStatusResponse)) {
      return false;
    }

    final LocatorStatusResponse that = (LocatorStatusResponse) obj;

    return ObjectUtils.equalsIgnoreNull(this.getPid(), that.getPid())
        && ObjectUtils.equals(this.getUptime(), that.getUptime())
        && ObjectUtils.equals(this.getWorkingDirectory(), that.getWorkingDirectory())
        && ObjectUtils.equals(this.getJvmArgs(), that.getJvmArgs())
        && ObjectUtils.equals(this.getClasspath(), that.getClasspath())
        && ObjectUtils.equals(this.getGemFireVersion(), that.getGemFireVersion())
        && ObjectUtils.equals(this.getJavaVersion(), that.getJavaVersion());
  }

  @Override
  public int hashCode() {
    int hashValue = 17;
    hashValue = 37 * hashValue + ObjectUtils.hashCode(getPid());
    hashValue = 37 * hashValue + ObjectUtils.hashCode(getUptime());
    hashValue = 37 * hashValue + ObjectUtils.hashCode(getWorkingDirectory());
    hashValue = 37 * hashValue + ObjectUtils.hashCode(getJvmArgs());
    hashValue = 37 * hashValue + ObjectUtils.hashCode(getClasspath());
    hashValue = 37 * hashValue + ObjectUtils.hashCode(getGemFireVersion());
    hashValue = 37 * hashValue + ObjectUtils.hashCode(getJavaVersion());
    return hashValue;
  }

  @Override
  public String toString() {
    final StringBuilder buffer = new StringBuilder(getClass().getSimpleName());
    buffer.append("{ pid = ").append(getPid());
    buffer.append(", uptime = ").append(getUptime());
    buffer.append(", workingDirectory = ").append(getWorkingDirectory());
    buffer.append(", jvmArgs = ").append(ArgumentRedactor.redact(getJvmArgs()));
    buffer.append(", classpath = ").append(getClasspath());
    buffer.append(", gemfireVersion = ").append(getGemFireVersion());
    buffer.append(", javaVersion = ").append(getJavaVersion());
    buffer.append("}");
    return buffer.toString();
  }

}
