/*
 * 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.iotdb.db.utils;

import org.apache.iotdb.db.auth.entity.PathPrivilege;

import java.io.DataInputStream;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.ByteBuffer;

public class IOUtils {

  private IOUtils() {}

  /**
   * Write a string into the given stream.
   *
   * @param outputStream the destination to insert.
   * @param str the string to be written.
   * @param encoding string encoding like 'utf-8'.
   * @param encodingBufferLocal a ThreadLocal buffer may be passed to avoid frequently memory
   *     allocations. A null may also be passed to use a local buffer.
   * @throws IOException when an exception raised during operating the stream.
   */
  public static void writeString(
      OutputStream outputStream,
      String str,
      String encoding,
      ThreadLocal<ByteBuffer> encodingBufferLocal)
      throws IOException {
    if (str != null) {
      byte[] strBuffer = str.getBytes(encoding);
      writeInt(outputStream, strBuffer.length, encodingBufferLocal);
      outputStream.write(strBuffer);
    } else {
      writeInt(outputStream, 0, encodingBufferLocal);
    }
  }

  /**
   * Write an integer into the given stream.
   *
   * @param outputStream the destination to insert.
   * @param i the integer to be written.
   * @param encodingBufferLocal a ThreadLocal buffer may be passed to avoid frequently memory
   *     allocations. A null may also be passed to use a local buffer.
   * @throws IOException when an exception raised during operating the stream.
   */
  public static void writeInt(
      OutputStream outputStream, int i, ThreadLocal<ByteBuffer> encodingBufferLocal)
      throws IOException {
    ByteBuffer encodingBuffer;
    if (encodingBufferLocal != null) {
      encodingBuffer = encodingBufferLocal.get();
      if (encodingBuffer == null) {
        // set to 8 because this buffer may be applied to other types
        encodingBuffer = ByteBuffer.allocate(8);
        encodingBufferLocal.set(encodingBuffer);
      }
    } else {
      encodingBuffer = ByteBuffer.allocate(4);
    }
    encodingBuffer.clear();
    encodingBuffer.putInt(i);
    outputStream.write(encodingBuffer.array(), 0, Integer.BYTES);
  }

  /**
   * Read a string from the given stream.
   *
   * @param inputStream the source to read.
   * @param encoding string encoding like 'utf-8'.
   * @param strBufferLocal a ThreadLocal buffer may be passed to avoid frequently memory
   *     allocations. A null may also be passed to use a local buffer.
   * @return a string read from the stream.
   * @throws IOException when an exception raised during operating the stream.
   */
  public static String readString(
      DataInputStream inputStream, String encoding, ThreadLocal<byte[]> strBufferLocal)
      throws IOException {
    byte[] strBuffer;
    int length = inputStream.readInt();
    if (length > 0) {
      if (strBufferLocal != null) {
        strBuffer = strBufferLocal.get();
        if (strBuffer == null || length > strBuffer.length) {
          strBuffer = new byte[length];
          strBufferLocal.set(strBuffer);
        }
      } else {
        strBuffer = new byte[length];
      }

      inputStream.read(strBuffer, 0, length);
      return new String(strBuffer, 0, length, encoding);
    }
    return null;
  }

  /**
   * Read a PathPrivilege from the given stream.
   *
   * @param inputStream the source to read.
   * @param encoding string encoding like 'utf-8'.
   * @param strBufferLocal a ThreadLocal buffer may be passed to avoid frequently memory
   *     allocations. A null may also be passed to use a local buffer.
   * @return a PathPrivilege read from the stream.
   * @throws IOException when an exception raised during operating the stream.
   */
  public static PathPrivilege readPathPrivilege(
      DataInputStream inputStream, String encoding, ThreadLocal<byte[]> strBufferLocal)
      throws IOException {
    String path = IOUtils.readString(inputStream, encoding, strBufferLocal);
    int privilegeNum = inputStream.readInt();
    PathPrivilege pathPrivilege = new PathPrivilege(path);
    for (int i = 0; i < privilegeNum; i++) {
      pathPrivilege.getPrivileges().add(inputStream.readInt());
    }
    return pathPrivilege;
  }

  /**
   * Write a PathPrivilege to the given stream.
   *
   * @param outputStream the destination to insert.
   * @param pathPrivilege the PathPrivilege to be written.
   * @param encoding string encoding like 'utf-8'.
   * @param encodingBufferLocal a ThreadLocal buffer may be passed to avoid frequently memory
   *     allocations. A null may also be passed to use a local buffer.
   * @throws IOException when an exception raised during operating the stream.
   */
  public static void writePathPrivilege(
      OutputStream outputStream,
      PathPrivilege pathPrivilege,
      String encoding,
      ThreadLocal<ByteBuffer> encodingBufferLocal)
      throws IOException {
    writeString(outputStream, pathPrivilege.getPath(), encoding, encodingBufferLocal);
    writeInt(outputStream, pathPrivilege.getPrivileges().size(), encodingBufferLocal);
    for (Integer i : pathPrivilege.getPrivileges()) {
      writeInt(outputStream, i, encodingBufferLocal);
    }
  }

  /**
   * Replace newFile with oldFile. If the file system does not support atomic file replacement then
   * delete the old file first.
   *
   * @param newFile the new file.
   * @param oldFile the file to be replaced.
   */
  public static void replaceFile(File newFile, File oldFile) throws IOException {
    if (!newFile.renameTo(oldFile)) {
      // some OSs need to delete the old file before renaming to it
      if (!oldFile.delete()) {
        throw new IOException(String.format("Cannot delete old user file : %s", oldFile.getPath()));
      }
      if (!newFile.renameTo(oldFile)) {
        throw new IOException(
            String.format("Cannot replace old user file with new one : %s", newFile.getPath()));
      }
    }
  }
}
