/*
 * 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.admin.internal;

import static org.apache.geode.distributed.ConfigurationProperties.MCAST_PORT;
import static org.apache.geode.internal.net.InetAddressUtilsWithLogging.toInetAddress;
import static org.apache.geode.internal.net.InetAddressUtilsWithLogging.validateHost;

import java.net.InetAddress;
import java.util.Properties;

import org.apache.geode.GemFireConfigException;
import org.apache.geode.admin.DistributionLocator;
import org.apache.geode.admin.DistributionLocatorConfig;
import org.apache.geode.distributed.internal.tcpserver.TcpClient;

/**
 * Provides an implementation of <code>DistributionLocatorConfig</code>.
 *
 * @since GemFire 4.0
 */
public class DistributionLocatorConfigImpl extends ManagedEntityConfigImpl
    implements DistributionLocatorConfig {

  /** The minimum networking port (0) */
  public static final int MIN_PORT = 0;

  /** The maximum networking port (65535) */
  public static final int MAX_PORT = 65535;

  ////////////////////// Instance Fields //////////////////////

  /** The port on which this locator listens */
  private int port;

  /** The address to bind to on a multi-homed host */
  private String bindAddress;

  /**
   * The properties used to configure the DistributionLocator's DistributedSystem
   */
  private Properties dsProperties;

  /** The DistributionLocator that was created with this config */
  private DistributionLocator locator;

  ////////////////////// Static Methods //////////////////////

  /**
   * Contacts a distribution locator on the given host and port and creates a
   * <code>DistributionLocatorConfig</code> for it.
   *
   * @see TcpClient#getLocatorInfo
   *
   * @return <code>null</code> if the locator cannot be contacted
   */
  static DistributionLocatorConfig createConfigFor(String host, int port, InetAddress bindAddress) {
    String[] info = new String[] {"unknown", "unknown"};

    try {
      TcpClient client = new TcpClient();
      if (bindAddress != null) {
        info = client.getInfo(bindAddress, port);
      } else {
        info = client.getInfo(toInetAddress(host), port);
      }
      if (info == null) {
        return null;
      }
    } catch (GemFireConfigException e) {
      // communications are not initialized at this point
    }

    DistributionLocatorConfigImpl config = new DistributionLocatorConfigImpl();
    config.setHost(host);
    config.setPort(port);
    if (bindAddress != null) {
      config.setBindAddress(bindAddress.getHostAddress());
    }
    config.setWorkingDirectory(info[0]);
    config.setProductDirectory(info[1]);

    return config;
  }

  /////////////////////// Constructors ///////////////////////

  /**
   * Creates a new <code>DistributionLocatorConfigImpl</code> with the default settings.
   */
  public DistributionLocatorConfigImpl() {
    this.port = 0;
    this.bindAddress = null;
    this.locator = null;
    this.dsProperties = new java.util.Properties();
    this.dsProperties.setProperty(MCAST_PORT, "0");
  }

  ///////////////////// Instance Methods /////////////////////

  /**
   * Sets the locator that was configured with this <Code>DistributionLocatorConfigImpl</code>.
   */
  void setLocator(DistributionLocator locator) {
    this.locator = locator;
  }

  @Override
  protected boolean isReadOnly() {
    return this.locator != null && this.locator.isRunning();
  }

  @Override
  public int getPort() {
    return this.port;
  }

  @Override
  public void setPort(int port) {
    checkReadOnly();
    this.port = port;
    configChanged();
  }

  @Override
  public String getBindAddress() {
    return this.bindAddress;
  }

  @Override
  public void setBindAddress(String bindAddress) {
    checkReadOnly();
    this.bindAddress = bindAddress;
    configChanged();
  }

  @Override
  public void setDistributedSystemProperties(Properties props) {
    this.dsProperties = props;
  }

  @Override
  public Properties getDistributedSystemProperties() {
    return this.dsProperties;
  }

  @Override
  public void validate() {
    super.validate();

    if (port < MIN_PORT || port > MAX_PORT) {
      throw new IllegalArgumentException(
          String.format("Port ( %s ) must be an integer between %s and %s",
              new Object[] {Integer.valueOf(port), Integer.valueOf(MIN_PORT),
                  Integer.valueOf(MAX_PORT)}));
    }

    if (this.bindAddress != null && validateHost(this.bindAddress) == null) {
      throw new IllegalArgumentException(
          String.format("Invalid host %s",
              this.bindAddress));
    }
  }

  /**
   * Currently, listeners are not supported on the locator config.
   */
  @Override
  protected void configChanged() {

  }

  @Override
  public Object clone() throws CloneNotSupportedException {
    DistributionLocatorConfigImpl clone = (DistributionLocatorConfigImpl) super.clone();
    clone.locator = null;
    return clone;
  }

  @Override
  public String toString() {
    StringBuilder sb = new StringBuilder();
    sb.append("DistributionLocatorConfig: host=").append(getHost());
    sb.append(", bindAddress=").append(getBindAddress());
    sb.append(", port=").append(getPort());
    return sb.toString();
  }
}
