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

import static org.apache.geode.logging.internal.spi.LogWriterLevel.INFO;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.util.List;
import java.util.Set;

import org.apache.geode.GemFireIOException;
import org.apache.geode.annotations.internal.MutableForTesting;
import org.apache.geode.distributed.internal.membership.InternalDistributedMember;
import org.apache.geode.distributed.internal.membership.gms.api.Membership;
import org.apache.geode.internal.logging.InternalLogWriter;
import org.apache.geode.internal.logging.PureLogWriter;

/**
 * A log intended for recording product-use.
 *
 * This class wraps a {@link InternalLogWriter} which it uses to record messages. It wipes the log
 * when it gets too large. The size of the log file is limited to 5mb by default and can be adjusted
 * with the system property <b>gemfire.max_product_use_file_size</b>, though the size is not allowed
 * to be less than 1mb.
 *
 * @since GemFire 2013
 */
public class ProductUseLog implements MembershipListener {
  @MutableForTesting
  protected static long MAX_PRODUCT_USE_FILE_SIZE = Long.getLong("max_view_log_size", 5000000);
  private final int logLevel;
  private final File productUseLogFile;
  private PureLogWriter logWriter;
  private InternalDistributedSystem system;

  static {
    // don't allow malicious setting of the file size to something too small
    if (MAX_PRODUCT_USE_FILE_SIZE < 1000000) {
      MAX_PRODUCT_USE_FILE_SIZE = 1000000;
    }
  }

  public ProductUseLog(File productUseLogFile) {
    // GEODE-4180, use absolute paths
    this.productUseLogFile = productUseLogFile.getAbsoluteFile();
    this.logLevel = INFO.intLevel();
    createLogWriter();
  }

  /**
   * adds the log as a membership listener to the given system and logs the view when members join
   */
  public void monitorUse(InternalDistributedSystem system) {
    this.system = system;
    DistributionManager dmgr = system.getDistributionManager();
    dmgr.addMembershipListener(this);
    Membership mmgr = dmgr.getMembershipManager();
    if (mmgr != null) {
      log("Log opened with new distributed system connection.  "
          + system.getDM().getMembershipManager().getView());
    } else { // membership manager not initialized?
      log("Log opened with new distributed system connection.  Membership view not yet available in this VM.");
    }
  }

  public synchronized void log(String logMessage) {
    if (!this.logWriter.isClosed()) {
      if (this.productUseLogFile.length() + logMessage.length() + 100 > MAX_PRODUCT_USE_FILE_SIZE) {
        clearLog();
      }
      this.logWriter.info(logMessage);
    }
  }

  /**
   * Closes the log. It may be reopened with reopen(). This does not remove the log from any
   * distributed systems it is monitoring.
   */
  public synchronized void close() {
    if (!this.logWriter.isClosed()) {
      this.logWriter.close();
    }
  }

  /**
   * returns true if the log has been closed
   */
  public synchronized boolean isClosed() {
    return this.logWriter.isClosed();
  }

  /** reopens a closed log */
  public synchronized void reopen() {
    if (this.logWriter.isClosed()) {
      createLogWriter();
    }
  }

  private synchronized void clearLog() {
    this.logWriter.close();
    this.productUseLogFile.delete();
    createLogWriter();
  }

  private synchronized void createLogWriter() {
    FileOutputStream fos;
    try {
      fos = new FileOutputStream(productUseLogFile, true);
    } catch (FileNotFoundException ex) {
      String s = String.format("Could not open log file %s.",
          productUseLogFile.getAbsolutePath());
      throw new GemFireIOException(s, ex);
    }
    PrintStream out = new PrintStream(fos);
    this.logWriter = new PureLogWriter(this.logLevel, out);
  }

  @Override
  public void memberJoined(DistributionManager distributionManager, InternalDistributedMember id) {
    log("A new member joined: " + id + ".  " + system.getDM().getMembershipManager().getView());
  }

  @Override
  public void memberDeparted(DistributionManager distributionManager, InternalDistributedMember id,
      boolean crashed) {}

  @Override
  public void memberSuspect(DistributionManager distributionManager, InternalDistributedMember id,
      InternalDistributedMember whoSuspected, String reason) {}

  @Override
  public void quorumLost(DistributionManager distributionManager,
      Set<InternalDistributedMember> failures, List<InternalDistributedMember> remaining) {}

}
