/*
 * 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.hadoop.hbase.snapshot;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URI;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.RegionInfo;
import org.apache.hadoop.hbase.client.SnapshotDescription;
import org.apache.hadoop.hbase.io.HFileLink;
import org.apache.hadoop.hbase.io.WALLink;
import org.apache.hadoop.hbase.util.AbstractHBaseTool;
import org.apache.hadoop.hbase.util.CommonFSUtils;
import org.apache.hadoop.util.StringUtils;
import org.apache.yetus.audience.InterfaceAudience;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.apache.hbase.thirdparty.org.apache.commons.cli.CommandLine;
import org.apache.hbase.thirdparty.org.apache.commons.cli.CommandLineParser;
import org.apache.hbase.thirdparty.org.apache.commons.cli.DefaultParser;
import org.apache.hbase.thirdparty.org.apache.commons.cli.Option;
import org.apache.hbase.thirdparty.org.apache.commons.cli.Options;
import org.apache.hbase.thirdparty.org.apache.commons.cli.ParseException;

import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil;
import org.apache.hadoop.hbase.shaded.protobuf.generated.SnapshotProtos;
import org.apache.hadoop.hbase.shaded.protobuf.generated.SnapshotProtos.SnapshotRegionManifest;

/**
 * Tool for dumping snapshot information.
 * <ol>
 * <li>Table Descriptor
 * <li>Snapshot creation time, type, format version, ...
 * <li>List of hfiles and wals
 * <li>Stats about hfiles and logs sizes, percentage of shared with the source table, ...
 * </ol>
 */
@InterfaceAudience.Public
public final class SnapshotInfo extends AbstractHBaseTool {
  private static final Logger LOG = LoggerFactory.getLogger(SnapshotInfo.class);

  static final class Options {
    static final Option SNAPSHOT =
      new Option(null, "snapshot", true, "The name of the snapshot to be detailed.");
    static final Option REMOTE_DIR =
      new Option(null, "remote-dir", true, "A custom root directory where snapshots are stored. "
        + "Use it together with the --snapshot option.");
    static final Option LIST_SNAPSHOTS =
      new Option(null, "list-snapshots", false, "List all the available snapshots and exit.");
    static final Option FILES =
      new Option(null, "files", false, "The list of files retained by the specified snapshot. "
        + "Use it together with the --snapshot option.");
    static final Option STATS =
      new Option(null, "stats", false, "Additional information about the specified snapshot. "
        + "Use it together with the --snapshot option.");
    static final Option SCHEMA = new Option(null, "schema", false,
      "Show the descriptor of the table for the specified snapshot. "
        + "Use it together with the --snapshot option.");
    static final Option SIZE_IN_BYTES =
      new Option(null, "size-in-bytes", false, "Print the size of the files in bytes. "
        + "Use it together with the --snapshot and --files options.");
  }

  /**
   * Statistics about the snapshot
   * <ol>
   * <li>How many store files and logs are in the archive
   * <li>How many store files and logs are shared with the table
   * <li>Total store files and logs size and shared amount
   * </ol>
   */
  public static class SnapshotStats {
    /** Information about the file referenced by the snapshot */
    static class FileInfo {
      private final boolean corrupted;
      private final boolean inArchive;
      private final long size;

      FileInfo(final boolean inArchive, final long size, final boolean corrupted) {
        this.corrupted = corrupted;
        this.inArchive = inArchive;
        this.size = size;
      }

      /** Returns true if the file is in the archive */
      public boolean inArchive() {
        return this.inArchive;
      }

      /** Returns true if the file is corrupted */
      public boolean isCorrupted() {
        return this.corrupted;
      }

      /** Returns true if the file is missing */
      public boolean isMissing() {
        return this.size < 0;
      }

      /** Returns the file size */
      public long getSize() {
        return this.size;
      }

      String getStateToString() {
        if (isCorrupted()) return "CORRUPTED";
        if (isMissing()) return "NOT FOUND";
        if (inArchive()) return "archive";
        return null;
      }
    }

    private AtomicInteger hfilesArchiveCount = new AtomicInteger();
    private AtomicInteger hfilesCorrupted = new AtomicInteger();
    private AtomicInteger hfilesMissing = new AtomicInteger();
    private AtomicInteger hfilesCount = new AtomicInteger();
    private AtomicInteger hfilesMobCount = new AtomicInteger();
    private AtomicInteger logsMissing = new AtomicInteger();
    private AtomicInteger logsCount = new AtomicInteger();
    private AtomicLong hfilesArchiveSize = new AtomicLong();
    private AtomicLong hfilesSize = new AtomicLong();
    private AtomicLong hfilesMobSize = new AtomicLong();
    private AtomicLong nonSharedHfilesArchiveSize = new AtomicLong();
    private AtomicLong logSize = new AtomicLong();

    private final SnapshotProtos.SnapshotDescription snapshot;
    private final TableName snapshotTable;
    private final Configuration conf;
    private final FileSystem fs;

    SnapshotStats(final Configuration conf, final FileSystem fs,
      final SnapshotDescription snapshot) {
      this.snapshot = ProtobufUtil.createHBaseProtosSnapshotDesc(snapshot);
      this.snapshotTable = snapshot.getTableName();
      this.conf = conf;
      this.fs = fs;
    }

    SnapshotStats(final Configuration conf, final FileSystem fs,
      final SnapshotProtos.SnapshotDescription snapshot) {
      this.snapshot = snapshot;
      this.snapshotTable = TableName.valueOf(snapshot.getTable());
      this.conf = conf;
      this.fs = fs;
    }

    /** Returns the snapshot descriptor */
    public SnapshotDescription getSnapshotDescription() {
      return ProtobufUtil.createSnapshotDesc(this.snapshot);
    }

    /** Returns true if the snapshot is corrupted */
    public boolean isSnapshotCorrupted() {
      return hfilesMissing.get() > 0 || logsMissing.get() > 0 || hfilesCorrupted.get() > 0;
    }

    /** Returns the number of available store files */
    public int getStoreFilesCount() {
      return hfilesCount.get() + hfilesArchiveCount.get() + hfilesMobCount.get();
    }

    /** Returns the number of available store files in the archive */
    public int getArchivedStoreFilesCount() {
      return hfilesArchiveCount.get();
    }

    /** Returns the number of available store files in the mob dir */
    public int getMobStoreFilesCount() {
      return hfilesMobCount.get();
    }

    /** Returns the number of available log files */
    public int getLogsCount() {
      return logsCount.get();
    }

    /** Returns the number of missing store files */
    public int getMissingStoreFilesCount() {
      return hfilesMissing.get();
    }

    /** Returns the number of corrupted store files */
    public int getCorruptedStoreFilesCount() {
      return hfilesCorrupted.get();
    }

    /** Returns the number of missing log files */
    public int getMissingLogsCount() {
      return logsMissing.get();
    }

    /** Returns the total size of the store files referenced by the snapshot */
    public long getStoreFilesSize() {
      return hfilesSize.get() + hfilesArchiveSize.get() + hfilesMobSize.get();
    }

    /** Returns the total size of the store files shared */
    public long getSharedStoreFilesSize() {
      return hfilesSize.get();
    }

    /** Returns the total size of the store files in the archive */
    public long getArchivedStoreFileSize() {
      return hfilesArchiveSize.get();
    }

    /** Returns the total size of the store files in the mob store */
    public long getMobStoreFilesSize() {
      return hfilesMobSize.get();
    }

    /**
     * @return the total size of the store files in the archive which is not shared with other
     *         snapshots and tables This is only calculated when
     *         {@link #getSnapshotStats(Configuration, SnapshotProtos.SnapshotDescription, Map)} is
     *         called with a non-null Map
     */
    public long getNonSharedArchivedStoreFilesSize() {
      return nonSharedHfilesArchiveSize.get();
    }

    /** Returns the percentage of the shared store files */
    public float getSharedStoreFilePercentage() {
      return ((float) hfilesSize.get() / (getStoreFilesSize())) * 100;
    }

    /** Returns the percentage of the mob store files */
    public float getMobStoreFilePercentage() {
      return ((float) hfilesMobSize.get() / (getStoreFilesSize())) * 100;
    }

    /** Returns the total log size */
    public long getLogsSize() {
      return logSize.get();
    }

    /**
     * Check if for a give file in archive, if there are other snapshots/tables still reference it.
     * @param filePath         file path in archive
     * @param snapshotFilesMap a map for store files in snapshots about how many snapshots refer to
     *                         it.
     * @return true or false
     */
    private boolean isArchivedFileStillReferenced(final Path filePath,
      final Map<Path, Integer> snapshotFilesMap) {

      Integer c = snapshotFilesMap.get(filePath);

      // Check if there are other snapshots or table from clone_snapshot() (via back-reference)
      // still reference to it.
      if ((c != null) && (c == 1)) {
        Path parentDir = filePath.getParent();
        Path backRefDir = HFileLink.getBackReferencesDir(parentDir, filePath.getName());
        try {
          if (CommonFSUtils.listStatus(fs, backRefDir) == null) {
            return false;
          }
        } catch (IOException e) {
          // For the purpose of this function, IOException is ignored and treated as
          // the file is still being referenced.
        }
      }
      return true;
    }

    /**
     * Add the specified store file to the stats
     * @param region    region encoded Name
     * @param family    family name
     * @param storeFile store file name
     * @param filesMap  store files map for all snapshots, it may be null
     * @return the store file information
     */
    FileInfo addStoreFile(final RegionInfo region, final String family,
      final SnapshotRegionManifest.StoreFile storeFile, final Map<Path, Integer> filesMap)
      throws IOException {
      HFileLink link =
        HFileLink.build(conf, snapshotTable, region.getEncodedName(), family, storeFile.getName());
      boolean isCorrupted = false;
      boolean inArchive = false;
      long size = -1;
      try {
        if (fs.exists(link.getArchivePath())) {
          inArchive = true;
          size = fs.getFileStatus(link.getArchivePath()).getLen();
          hfilesArchiveSize.addAndGet(size);
          hfilesArchiveCount.incrementAndGet();

          // If store file is not shared with other snapshots and tables,
          // increase nonSharedHfilesArchiveSize
          if (
            (filesMap != null) && !isArchivedFileStillReferenced(link.getArchivePath(), filesMap)
          ) {
            nonSharedHfilesArchiveSize.addAndGet(size);
          }
        } else if (fs.exists(link.getMobPath())) {
          inArchive = true;
          size = fs.getFileStatus(link.getMobPath()).getLen();
          hfilesMobSize.addAndGet(size);
          hfilesMobCount.incrementAndGet();
        } else {
          size = link.getFileStatus(fs).getLen();
          hfilesSize.addAndGet(size);
          hfilesCount.incrementAndGet();
        }
        isCorrupted = (storeFile.hasFileSize() && storeFile.getFileSize() != size);
        if (isCorrupted) hfilesCorrupted.incrementAndGet();
      } catch (FileNotFoundException e) {
        hfilesMissing.incrementAndGet();
      }
      return new FileInfo(inArchive, size, isCorrupted);
    }

    /**
     * Add the specified log file to the stats
     * @param server  server name
     * @param logfile log file name
     * @return the log information
     */
    FileInfo addLogFile(final String server, final String logfile) throws IOException {
      WALLink logLink = new WALLink(conf, server, logfile);
      long size = -1;
      try {
        size = logLink.getFileStatus(fs).getLen();
        logSize.addAndGet(size);
        logsCount.incrementAndGet();
      } catch (FileNotFoundException e) {
        logsMissing.incrementAndGet();
      }
      return new FileInfo(false, size, false);
    }
  }

  private FileSystem fs;
  private Path rootDir;

  private SnapshotManifest snapshotManifest;

  private boolean listSnapshots = false;
  private String snapshotName;
  private Path remoteDir;
  private boolean showSchema = false;
  private boolean showFiles = false;
  private boolean showStats = false;
  private boolean printSizeInBytes = false;

  @Override
  public int doWork() throws IOException, InterruptedException {
    if (remoteDir != null) {
      URI defaultFs = remoteDir.getFileSystem(conf).getUri();
      CommonFSUtils.setFsDefault(conf, new Path(defaultFs));
      CommonFSUtils.setRootDir(conf, remoteDir);
    }

    // List Available Snapshots
    if (listSnapshots) {
      SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
      System.out.printf("%-20s | %-20s | %-20s | %s%n", "SNAPSHOT", "CREATION TIME", "TTL IN SEC",
        "TABLE NAME");
      for (SnapshotDescription desc : getSnapshotList(conf)) {
        System.out.printf("%-20s | %20s | %20s | %s%n", desc.getName(),
          df.format(new Date(desc.getCreationTime())), desc.getTtl(), desc.getTableNameAsString());
      }
      return 0;
    }

    rootDir = CommonFSUtils.getRootDir(conf);
    fs = FileSystem.get(rootDir.toUri(), conf);
    LOG.debug("fs=" + fs.getUri().toString() + " root=" + rootDir);

    // Load snapshot information
    if (!loadSnapshotInfo(snapshotName)) {
      System.err.println("Snapshot '" + snapshotName + "' not found!");
      return 1;
    }

    printInfo();
    if (showSchema) {
      printSchema();
    }
    printFiles(showFiles, showStats);

    return 0;
  }

  /**
   * Load snapshot info and table descriptor for the specified snapshot
   * @param snapshotName name of the snapshot to load
   * @return false if snapshot is not found
   */
  private boolean loadSnapshotInfo(final String snapshotName) throws IOException {
    Path snapshotDir = SnapshotDescriptionUtils.getCompletedSnapshotDir(snapshotName, rootDir);
    if (!fs.exists(snapshotDir)) {
      LOG.warn("Snapshot '" + snapshotName + "' not found in: " + snapshotDir);
      return false;
    }

    SnapshotProtos.SnapshotDescription snapshotDesc =
      SnapshotDescriptionUtils.readSnapshotInfo(fs, snapshotDir);
    snapshotManifest = SnapshotManifest.open(getConf(), fs, snapshotDir, snapshotDesc);
    return true;
  }

  /**
   * Dump the {@link SnapshotDescription}
   */
  private void printInfo() {
    SnapshotProtos.SnapshotDescription snapshotDesc = snapshotManifest.getSnapshotDescription();
    SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
    System.out.println("Snapshot Info");
    System.out.println("----------------------------------------");
    System.out.println("   Name: " + snapshotDesc.getName());
    System.out.println("   Type: " + snapshotDesc.getType());
    System.out.println("  Table: " + snapshotDesc.getTable());
    System.out.println(" Format: " + snapshotDesc.getVersion());
    System.out.println("Created: " + df.format(new Date(snapshotDesc.getCreationTime())));
    System.out.println("    Ttl: " + snapshotDesc.getTtl());
    System.out.println("  Owner: " + snapshotDesc.getOwner());
    System.out.println();
  }

  /**
   * Dump the {@link org.apache.hadoop.hbase.client.TableDescriptor}
   */
  private void printSchema() {
    System.out.println("Table Descriptor");
    System.out.println("----------------------------------------");
    System.out.println(snapshotManifest.getTableDescriptor().toString());
    System.out.println();
  }

  /**
   * Collect the hfiles and logs statistics of the snapshot and dump the file list if requested and
   * the collected information.
   */
  private void printFiles(final boolean showFiles, final boolean showStats) throws IOException {
    if (showFiles) {
      System.out.println("Snapshot Files");
      System.out.println("----------------------------------------");
    }

    // Collect information about hfiles and logs in the snapshot
    final SnapshotProtos.SnapshotDescription snapshotDesc =
      snapshotManifest.getSnapshotDescription();
    final String table = snapshotDesc.getTable();
    final SnapshotDescription desc = ProtobufUtil.createSnapshotDesc(snapshotDesc);
    final SnapshotStats stats = new SnapshotStats(this.getConf(), this.fs, desc);
    SnapshotReferenceUtil.concurrentVisitReferencedFiles(getConf(), fs, snapshotManifest,
      "SnapshotInfo", new SnapshotReferenceUtil.SnapshotVisitor() {
        @Override
        public void storeFile(final RegionInfo regionInfo, final String family,
          final SnapshotRegionManifest.StoreFile storeFile) throws IOException {
          if (storeFile.hasReference()) return;

          SnapshotStats.FileInfo info = stats.addStoreFile(regionInfo, family, storeFile, null);
          if (showFiles) {
            String state = info.getStateToString();
            System.out.printf("%8s %s/%s/%s/%s %s%n",
              (info.isMissing() ? "-" : fileSizeToString(info.getSize())), table,
              regionInfo.getEncodedName(), family, storeFile.getName(),
              state == null ? "" : "(" + state + ")");
          }
        }
      });

    // Dump the stats
    System.out.println();
    if (stats.isSnapshotCorrupted()) {
      System.out.println("**************************************************************");
      System.out.printf("BAD SNAPSHOT: %d hfile(s) and %d log(s) missing.%n",
        stats.getMissingStoreFilesCount(), stats.getMissingLogsCount());
      System.out.printf("              %d hfile(s) corrupted.%n",
        stats.getCorruptedStoreFilesCount());
      System.out.println("**************************************************************");
    }

    if (showStats) {
      System.out.printf(
        "%d HFiles (%d in archive, %d in mob storage), total size %s "
          + "(%.2f%% %s shared with the source table, %.2f%% %s in mob dir)%n",
        stats.getStoreFilesCount(), stats.getArchivedStoreFilesCount(),
        stats.getMobStoreFilesCount(), fileSizeToString(stats.getStoreFilesSize()),
        stats.getSharedStoreFilePercentage(), fileSizeToString(stats.getSharedStoreFilesSize()),
        stats.getMobStoreFilePercentage(), fileSizeToString(stats.getMobStoreFilesSize()));
      System.out.printf("%d Logs, total size %s%n", stats.getLogsCount(),
        fileSizeToString(stats.getLogsSize()));
      System.out.println();
    }
  }

  private String fileSizeToString(long size) {
    return printSizeInBytes ? Long.toString(size) : StringUtils.humanReadableInt(size);
  }

  @Override
  protected void addOptions() {
    addOption(Options.SNAPSHOT);
    addOption(Options.REMOTE_DIR);
    addOption(Options.LIST_SNAPSHOTS);
    addOption(Options.FILES);
    addOption(Options.STATS);
    addOption(Options.SCHEMA);
    addOption(Options.SIZE_IN_BYTES);
  }

  @Override
  protected CommandLineParser newParser() {
    // Commons-CLI lacks the capability to handle combinations of options, so we do it ourselves
    // Validate in parse() to get helpful error messages instead of exploding in processOptions()
    return new DefaultParser() {
      @Override
      public CommandLine parse(org.apache.hbase.thirdparty.org.apache.commons.cli.Options opts,
        String[] args, Properties props, boolean stop) throws ParseException {
        CommandLine cl = super.parse(opts, args, props, stop);
        if (!cmd.hasOption(Options.LIST_SNAPSHOTS) && !cmd.hasOption(Options.SNAPSHOT)) {
          throw new ParseException("Missing required snapshot option!");
        }
        return cl;
      }
    };
  }

  @Override
  protected void processOptions(CommandLine cmd) {
    snapshotName = cmd.getOptionValue(Options.SNAPSHOT.getLongOpt());
    showFiles = cmd.hasOption(Options.FILES.getLongOpt());
    showStats =
      cmd.hasOption(Options.FILES.getLongOpt()) || cmd.hasOption(Options.STATS.getLongOpt());
    showSchema = cmd.hasOption(Options.SCHEMA.getLongOpt());
    listSnapshots = cmd.hasOption(Options.LIST_SNAPSHOTS.getLongOpt());
    printSizeInBytes = cmd.hasOption(Options.SIZE_IN_BYTES.getLongOpt());
    if (cmd.hasOption(Options.REMOTE_DIR.getLongOpt())) {
      remoteDir = new Path(cmd.getOptionValue(Options.REMOTE_DIR.getLongOpt()));
    }
  }

  @Override
  protected void printUsage() {
    printUsage("hbase snapshot info [options]", "Options:", "");
    System.err.println("Examples:");
    System.err.println("  hbase snapshot info --snapshot MySnapshot --files");
  }

  /**
   * Returns the snapshot stats
   * @param conf     the {@link Configuration} to use
   * @param snapshot {@link SnapshotDescription} to get stats from
   * @return the snapshot stats
   */
  public static SnapshotStats getSnapshotStats(final Configuration conf,
    final SnapshotDescription snapshot) throws IOException {
    SnapshotProtos.SnapshotDescription snapshotDesc =
      ProtobufUtil.createHBaseProtosSnapshotDesc(snapshot);
    return getSnapshotStats(conf, snapshotDesc, null);
  }

  /**
   * Returns the snapshot stats
   * @param conf         the {@link Configuration} to use
   * @param snapshotDesc HBaseProtos.SnapshotDescription to get stats from
   * @param filesMap     {@link Map} store files map for all snapshots, it may be null
   * @return the snapshot stats
   */
  public static SnapshotStats getSnapshotStats(final Configuration conf,
    final SnapshotProtos.SnapshotDescription snapshotDesc, final Map<Path, Integer> filesMap)
    throws IOException {
    Path rootDir = CommonFSUtils.getRootDir(conf);
    FileSystem fs = FileSystem.get(rootDir.toUri(), conf);
    Path snapshotDir = SnapshotDescriptionUtils.getCompletedSnapshotDir(snapshotDesc, rootDir);
    SnapshotManifest manifest = SnapshotManifest.open(conf, fs, snapshotDir, snapshotDesc);
    final SnapshotStats stats = new SnapshotStats(conf, fs, snapshotDesc);
    SnapshotReferenceUtil.concurrentVisitReferencedFiles(conf, fs, manifest,
      "SnapshotsStatsAggregation", new SnapshotReferenceUtil.SnapshotVisitor() {
        @Override
        public void storeFile(final RegionInfo regionInfo, final String family,
          final SnapshotRegionManifest.StoreFile storeFile) throws IOException {
          if (!storeFile.hasReference()) {
            stats.addStoreFile(regionInfo, family, storeFile, filesMap);
          }
        }
      });
    return stats;
  }

  /**
   * Returns the list of available snapshots in the specified location
   * @param conf the {@link Configuration} to use
   * @return the list of snapshots
   */
  public static List<SnapshotDescription> getSnapshotList(final Configuration conf)
    throws IOException {
    Path rootDir = CommonFSUtils.getRootDir(conf);
    FileSystem fs = FileSystem.get(rootDir.toUri(), conf);
    Path snapshotDir = SnapshotDescriptionUtils.getSnapshotsDir(rootDir);
    FileStatus[] snapshots = fs.listStatus(snapshotDir,
      new SnapshotDescriptionUtils.CompletedSnaphotDirectoriesFilter(fs));
    List<SnapshotDescription> snapshotLists = new ArrayList<>(snapshots.length);
    for (FileStatus snapshotDirStat : snapshots) {
      SnapshotProtos.SnapshotDescription snapshotDesc =
        SnapshotDescriptionUtils.readSnapshotInfo(fs, snapshotDirStat.getPath());
      snapshotLists.add(ProtobufUtil.createSnapshotDesc(snapshotDesc));
    }
    return snapshotLists;
  }

  /**
   * Gets the store files map for snapshot
   * @param conf                    the {@link Configuration} to use
   * @param snapshot                {@link SnapshotDescription} to get stats from
   * @param exec                    the {@link ExecutorService} to use
   * @param filesMap                {@link Map} the map to put the mapping entries
   * @param uniqueHFilesArchiveSize {@link AtomicLong} the accumulated store file size in archive
   * @param uniqueHFilesSize        {@link AtomicLong} the accumulated store file size shared
   * @param uniqueHFilesMobSize     {@link AtomicLong} the accumulated mob store file size shared
   */
  private static void getSnapshotFilesMap(final Configuration conf,
    final SnapshotDescription snapshot, final ExecutorService exec,
    final ConcurrentHashMap<Path, Integer> filesMap, final AtomicLong uniqueHFilesArchiveSize,
    final AtomicLong uniqueHFilesSize, final AtomicLong uniqueHFilesMobSize) throws IOException {
    SnapshotProtos.SnapshotDescription snapshotDesc =
      ProtobufUtil.createHBaseProtosSnapshotDesc(snapshot);
    Path rootDir = CommonFSUtils.getRootDir(conf);
    final FileSystem fs = FileSystem.get(rootDir.toUri(), conf);

    Path snapshotDir = SnapshotDescriptionUtils.getCompletedSnapshotDir(snapshotDesc, rootDir);
    SnapshotManifest manifest = SnapshotManifest.open(conf, fs, snapshotDir, snapshotDesc);
    SnapshotReferenceUtil.concurrentVisitReferencedFiles(conf, fs, manifest, exec,
      new SnapshotReferenceUtil.SnapshotVisitor() {
        @Override
        public void storeFile(final RegionInfo regionInfo, final String family,
          final SnapshotRegionManifest.StoreFile storeFile) throws IOException {
          if (!storeFile.hasReference()) {
            HFileLink link = HFileLink.build(conf, snapshot.getTableName(),
              regionInfo.getEncodedName(), family, storeFile.getName());
            long size;
            Integer count;
            Path p;
            AtomicLong al;
            int c = 0;

            if (fs.exists(link.getArchivePath())) {
              p = link.getArchivePath();
              al = uniqueHFilesArchiveSize;
              size = fs.getFileStatus(p).getLen();
            } else if (fs.exists(link.getMobPath())) {
              p = link.getMobPath();
              al = uniqueHFilesMobSize;
              size = fs.getFileStatus(p).getLen();
            } else {
              p = link.getOriginPath();
              al = uniqueHFilesSize;
              size = link.getFileStatus(fs).getLen();
            }

            // If it has been counted, do not double count
            count = filesMap.get(p);
            if (count != null) {
              c = count.intValue();
            } else {
              al.addAndGet(size);
            }

            filesMap.put(p, ++c);
          }
        }
      });
  }

  /**
   * Returns the map of store files based on path for all snapshots
   * @param conf                    the {@link Configuration} to use
   * @param uniqueHFilesArchiveSize pass out the size for store files in archive
   * @param uniqueHFilesSize        pass out the size for store files shared
   * @param uniqueHFilesMobSize     pass out the size for mob store files shared
   * @return the map of store files
   */
  public static Map<Path, Integer> getSnapshotsFilesMap(final Configuration conf,
    AtomicLong uniqueHFilesArchiveSize, AtomicLong uniqueHFilesSize, AtomicLong uniqueHFilesMobSize)
    throws IOException {
    List<SnapshotDescription> snapshotList = getSnapshotList(conf);

    if (snapshotList.isEmpty()) {
      return Collections.emptyMap();
    }

    ConcurrentHashMap<Path, Integer> fileMap = new ConcurrentHashMap<>();

    ExecutorService exec = SnapshotManifest.createExecutor(conf, "SnapshotsFilesMapping");

    try {
      for (final SnapshotDescription snapshot : snapshotList) {
        getSnapshotFilesMap(conf, snapshot, exec, fileMap, uniqueHFilesArchiveSize,
          uniqueHFilesSize, uniqueHFilesMobSize);
      }
    } finally {
      exec.shutdown();
    }

    return fileMap;
  }

  public static void main(String[] args) {
    new SnapshotInfo().doStaticMain(args);
  }
}
