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

import java.io.*;
import java.lang.reflect.Field;
import java.nio.MappedByteBuffer;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.FileChannel;
import java.util.concurrent.atomic.AtomicInteger;

import org.apache.cassandra.config.Config;

import com.google.common.base.Preconditions;
import org.apache.cassandra.io.util.File;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/*
 * A wrapper around various mechanisms for syncing files that makes it possible it intercept
 * and skip syncing. Useful for unit tests in certain environments where syncs can have outliers
 * bad enough to causes tests to run 10s of seconds longer.
 */
public class SyncUtil
{
    public static final boolean SKIP_SYNC;

    private static final Field mbbFDField;
    private static final Field fdClosedField;
    private static final Field fdUseCountField;

    private static final Logger logger = LoggerFactory.getLogger(SyncUtil.class);

    static
    {
        Field mbbFDFieldTemp = null;
        try
        {
            mbbFDFieldTemp = MappedByteBuffer.class.getDeclaredField("fd");
            mbbFDFieldTemp.setAccessible(true);
        }
        catch (NoSuchFieldException e)
        {
        }
        mbbFDField = mbbFDFieldTemp;

        //Java 8
        Field fdClosedFieldTemp = null;
        try
        {
            fdClosedFieldTemp = FileDescriptor.class.getDeclaredField("closed");
            fdClosedFieldTemp.setAccessible(true);
        }
        catch (NoSuchFieldException e)
        {
        }
        fdClosedField = fdClosedFieldTemp;

        //Java 7
        Field fdUseCountTemp = null;
        try
        {
            fdUseCountTemp = FileDescriptor.class.getDeclaredField("useCount");
            fdUseCountTemp.setAccessible(true);
        }
        catch (NoSuchFieldException e)
        {
        }
        fdUseCountField = fdUseCountTemp;

        //If skipping syncing is requested by any means then skip them.
        boolean skipSyncProperty = Boolean.getBoolean(Config.PROPERTY_PREFIX + "skip_sync");
        boolean skipSyncEnv = Boolean.valueOf(System.getenv().getOrDefault("CASSANDRA_SKIP_SYNC", "false"));
        SKIP_SYNC = skipSyncProperty || skipSyncEnv;
        if (SKIP_SYNC)
        {
            logger.info("Skip fsync enabled due to property {} and environment {}", skipSyncProperty, skipSyncEnv);
        }
    }

    public static MappedByteBuffer force(MappedByteBuffer buf)
    {
        Preconditions.checkNotNull(buf);
        if (SKIP_SYNC)
        {
            Object fd = null;
            try
            {
                if (mbbFDField != null)
                {
                    fd = mbbFDField.get(buf);
                }
            }
            catch (Exception e)
            {
                throw new RuntimeException(e);
            }
            //This is what MappedByteBuffer.force() throws if a you call force() on an umapped buffer
            if (mbbFDField != null && fd == null)
                throw new UnsupportedOperationException();
            return buf;
        }
        else
        {
            return buf.force();
        }
    }

    public static void sync(FileDescriptor fd) throws SyncFailedException
    {
        Preconditions.checkNotNull(fd);
        if (SKIP_SYNC)
        {
            boolean closed = false;
            try
            {
                if (fdClosedField != null)
                    closed = fdClosedField.getBoolean(fd);
            }
            catch (Exception e)
            {
                throw new RuntimeException(e);
            }

            int useCount = 1;
            try
            {
                if (fdUseCountField != null)
                    useCount = ((AtomicInteger)fdUseCountField.get(fd)).get();
            }
            catch (Exception e)
            {
                throw new RuntimeException(e);
            }
            if (closed || !fd.valid() || useCount < 0)
                throw new SyncFailedException("Closed " + closed + " valid " + fd.valid() + " useCount " + useCount);
        }
        else
        {
            fd.sync();
        }
    }

    public static void force(FileChannel fc, boolean metaData) throws IOException
    {
        Preconditions.checkNotNull(fc);
        if (SKIP_SYNC)
        {
            if (!fc.isOpen())
                throw new ClosedChannelException();
        }
        else
        {
            fc.force(metaData);
        }
    }

    public static void sync(FileOutputStream fos) throws IOException
    {
        Preconditions.checkNotNull(fos);
        sync(fos.getFD());
    }

    public static void trySync(int fd)
    {
        if (SKIP_SYNC)
            return;
        else
            NativeLibrary.trySync(fd);
    }

    public static void trySyncDir(File dir)
    {
        if (SKIP_SYNC)
            return;

        int directoryFD = NativeLibrary.tryOpenDirectory(dir.path());
        try
        {
            trySync(directoryFD);
        }
        finally
        {
            NativeLibrary.tryCloseFD(directoryFD);
        }
    }
}
