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

import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Collection;
import java.util.Map;
import java.util.stream.Collectors;

import org.apache.logging.log4j.Logger;

import org.apache.geode.cache.lucene.internal.IndexRepositoryFactory;
import org.apache.geode.logging.internal.log4j.api.LogService;

/**
 * A Filesystem like interface that stores file data in geode regions.
 *
 * This filesystem is safe for use with multiple threads if the threads are not modifying the same
 * files. A single file is not safe to modify by multiple threads, even between different members of
 * the distributed system.
 *
 * Changes to a file may not be visible to other members of the system until the FileOutputStream is
 * closed.
 *
 */
public class FileSystem {
  private static final Logger logger = LogService.getLogger();

  private final Map fileAndChunkRegion;

  static final int CHUNK_SIZE = 1024 * 1024; // 1 MB
  private final FileSystemStats stats;

  /**
   * Create filesystem that will store data in the two provided regions. The fileAndChunkRegion
   * contains metadata about the files, and the chunkRegion contains the actual data. If data from
   * either region is missing or inconsistent, no guarantees are made about what this class will do,
   * so it's best if these regions are colocated and in the same disk store to ensure the data
   * remains together.
   *
   * @param fileAndChunkRegion the region to store metadata about the files
   */
  public FileSystem(Map fileAndChunkRegion, FileSystemStats stats) {
    this.fileAndChunkRegion = fileAndChunkRegion;
    this.stats = stats;
  }

  public Collection<String> listFileNames() {
    return (Collection<String>) fileAndChunkRegion.keySet().stream()
        .filter(entry -> ((entry instanceof String) && !((String) entry)
            .equalsIgnoreCase(IndexRepositoryFactory.APACHE_GEODE_INDEX_COMPLETE)))
        .collect(Collectors.toList());
  }

  public File createFile(final String name) throws IOException {
    // TODO lock region ?
    final File file = new File(this, name);
    if (null != fileAndChunkRegion.putIfAbsent(name, file)) {
      throw new IOException("File exists.");
    }
    stats.incFileCreates(1);

    // TODO unlock region ?
    return file;
  }

  public File putIfAbsentFile(String name, File file) throws IOException {
    // TODO lock region ?
    if (null != fileAndChunkRegion.putIfAbsent(name, file)) {
      throw new IOException("File exists.");
    }
    stats.incFileCreates(1);
    // TODO unlock region ?
    return file;
  }

  public File createTemporaryFile(final String name) throws IOException {
    final File file = new File(this, name);
    stats.incTemporaryFileCreates(1);
    return file;
  }

  public File getFile(final String name) throws FileNotFoundException {
    final File file = (File) fileAndChunkRegion.get(name);

    if (null == file) {
      throw new FileNotFoundException(name);
    }

    file.setFileSystem(this);
    return file;
  }

  public void deleteFile(final String name) throws FileNotFoundException {
    // TODO locks?

    // TODO - What is the state of the system if
    // things crash in the middle of removing this file?
    // Seems like a file will be left with some
    // dangling chunks at the end of the file
    File file = (File) fileAndChunkRegion.remove(name);
    if (file == null) {
      throw new FileNotFoundException(name);
    }

    if (file.possiblyRenamed == false) {
      // TODO consider removeAll with all ChunkKeys listed.
      final ChunkKey key = new ChunkKey(file.id, 0);
      while (true) {
        // TODO consider mutable ChunkKey
        if (null == fileAndChunkRegion.remove(key)) {
          // no more chunks
          break;
        }
        key.chunkId++;
      }
    }
    stats.incFileDeletes(1);
  }

  public void renameFile(String source, String dest) throws IOException {

    final File sourceFile = (File) fileAndChunkRegion.get(source);
    if (null == sourceFile) {
      throw new FileNotFoundException(source);
    }

    final File destFile = new File(this, dest);
    destFile.chunks = sourceFile.chunks;
    destFile.created = sourceFile.created;
    destFile.length = sourceFile.length;
    destFile.modified = sourceFile.modified;
    destFile.id = sourceFile.id;
    sourceFile.possiblyRenamed = true;
    // TODO - What is the state of the system if
    // things crash in the middle of moving this file?
    // Seems like we will have two files pointing
    // at the same data
    updateFile(sourceFile);
    putIfAbsentFile(dest, destFile);

    fileAndChunkRegion.remove(source);
    stats.incFileRenames(1);
  }

  byte[] getChunk(final File file, final int id) {
    final ChunkKey key = new ChunkKey(file.id, id);

    // The file's metadata indicates that this chunk shouldn't
    // exist. Purge all of the chunks that are larger than the file metadata
    if (id >= file.chunks) {
      while (fileAndChunkRegion.containsKey(key)) {
        fileAndChunkRegion.remove(key);
        key.chunkId++;
      }
      return null;
    }

    final byte[] chunk = (byte[]) fileAndChunkRegion.get(key);
    if (chunk != null) {
      stats.incReadBytes(chunk.length);
    } else {
      logger.debug("Chunk was null for file:" + file.getName() + " file id: " + key.getFileId()
          + " chunkKey:" + key.chunkId);
    }
    return chunk;
  }

  public void putChunk(final File file, final int id, final byte[] chunk) {
    final ChunkKey key = new ChunkKey(file.id, id);
    fileAndChunkRegion.put(key, chunk);
    stats.incWrittenBytes(chunk.length);
  }

  void updateFile(File file) {
    fileAndChunkRegion.put(file.getName(), file);
  }

  public Map getFileAndChunkRegion() {
    return fileAndChunkRegion;
  }


  /**
   * Export all of the files in the filesystem to the provided directory
   */
  public void export(final java.io.File exportLocation) {

    listFileNames().stream().forEach(fileName -> {
      try {
        getFile(fileName).export(exportLocation);
      } catch (FileNotFoundException e) {
        // ignore this, it was concurrently removed
      }
    });
  }

}
