package org.eclipse.aether.connector.basic;

/*
 * 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.
 */

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.Closeable;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.channels.Channel;
import java.nio.channels.FileLock;
import java.nio.channels.OverlappingFileLockException;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * A partially downloaded file with optional support for resume. If resume is enabled, a well-known location is used for
 * the partial file in combination with a lock file to prevent concurrent requests from corrupting it (and wasting
 * network bandwith). Otherwise, a (non-locked) unique temporary file is used.
 */
final class PartialFile
    implements Closeable
{

    static final String EXT_PART = ".part";

    static final String EXT_LOCK = ".lock";

    interface RemoteAccessChecker
    {

        void checkRemoteAccess()
            throws Exception;

    }

    static class LockFile
    {

        private final File lockFile;

        private final FileLock lock;

        private final AtomicBoolean concurrent;

        LockFile( File partFile, int requestTimeout, RemoteAccessChecker checker )
            throws Exception
        {
            lockFile = new File( partFile.getPath() + EXT_LOCK );
            concurrent = new AtomicBoolean( false );
            lock = lock( lockFile, partFile, requestTimeout, checker, concurrent );
        }

        private static FileLock lock( File lockFile, File partFile, int requestTimeout, RemoteAccessChecker checker,
                                      AtomicBoolean concurrent )
            throws Exception
        {
            boolean interrupted = false;
            try
            {
                for ( long lastLength = -1L, lastTime = 0L;; )
                {
                    FileLock lock = tryLock( lockFile );
                    if ( lock != null )
                    {
                        return lock;
                    }

                    long currentLength = partFile.length();
                    long currentTime = System.currentTimeMillis();
                    if ( currentLength != lastLength )
                    {
                        if ( lastLength < 0L )
                        {
                            concurrent.set( true );
                            /*
                             * NOTE: We're going with the optimistic assumption that the other thread is downloading the
                             * file from an equivalent repository. As a bare minimum, ensure the repository we are given
                             * at least knows about the file and is accessible to us.
                             */
                            checker.checkRemoteAccess();
                            LOGGER.debug( "Concurrent download of {} in progress, awaiting completion", partFile );
                        }
                        lastLength = currentLength;
                        lastTime = currentTime;
                    }
                    else if ( requestTimeout > 0 && currentTime - lastTime > Math.max( requestTimeout, 3 * 1000 ) )
                    {
                        throw new IOException( "Timeout while waiting for concurrent download of " + partFile
                                                   + " to progress" );
                    }

                    try
                    {
                        Thread.sleep( 100 );
                    }
                    catch ( InterruptedException e )
                    {
                        interrupted = true;
                    }
                }
            }
            finally
            {
                if ( interrupted )
                {
                    Thread.currentThread().interrupt();
                }
            }
        }

        private static FileLock tryLock( File lockFile )
            throws IOException
        {
            RandomAccessFile raf = null;
            FileLock lock = null;
            try
            {
                raf = new RandomAccessFile( lockFile, "rw" );
                lock = raf.getChannel().tryLock( 0, 1, false );

                if ( lock == null )
                {
                    raf.close();
                    raf = null;
                }
            }
            catch ( OverlappingFileLockException e )
            {
                close( raf );
                raf = null;
                lock = null;
            }
            catch ( RuntimeException | IOException e )
            {
                close( raf );
                raf = null;
                if ( !lockFile.delete() )
                {
                    lockFile.deleteOnExit();
                }
                throw e;
            }
            finally
            {
                try
                {
                    if ( lock == null && raf != null )
                    {
                        raf.close();
                    }
                }
                catch ( final IOException e )
                {
                    // Suppressed due to an exception already thrown in the try block.
                }
            }

            return lock;
        }

        private static void close( Closeable file )
        {
            try
            {
                if ( file != null )
                {
                    file.close();
                }
            }
            catch ( IOException e )
            {
                // Suppressed.
            }
        }

        public boolean isConcurrent()
        {
            return concurrent.get();
        }

        public void close() throws IOException
        {
            Channel channel = null;
            try
            {
                channel = lock.channel();
                lock.release();
                channel.close();
                channel = null;
            }
            finally
            {
                try
                {
                    if ( channel != null )
                    {
                        channel.close();
                    }
                }
                catch ( final IOException e )
                {
                    // Suppressed due to an exception already thrown in the try block.
                }
                finally
                {
                    if ( !lockFile.delete() )
                    {
                        lockFile.deleteOnExit();
                    }
                }
            }
        }

        @Override
        public String toString()
        {
            return lockFile + " - " + lock.isValid();
        }

    }

    static class Factory
    {

        private final boolean resume;

        private final long resumeThreshold;

        private final int requestTimeout;

        private static final Logger LOGGER = LoggerFactory.getLogger( Factory.class );

        Factory( boolean resume, long resumeThreshold, int requestTimeout )
        {
            this.resume = resume;
            this.resumeThreshold = resumeThreshold;
            this.requestTimeout = requestTimeout;
        }

        public PartialFile newInstance( File dstFile, RemoteAccessChecker checker )
            throws Exception
        {
            if ( resume )
            {
                File partFile = new File( dstFile.getPath() + EXT_PART );

                long reqTimestamp = System.currentTimeMillis();
                LockFile lockFile = new LockFile( partFile, requestTimeout, checker );
                if ( lockFile.isConcurrent() && dstFile.lastModified() >= reqTimestamp - 100L )
                {
                    lockFile.close();
                    return null;
                }
                try
                {
                    if ( !partFile.createNewFile() && !partFile.isFile() )
                    {
                        throw new IOException( partFile.exists() ? "Path exists but is not a file" : "Unknown error" );
                    }
                    return new PartialFile( partFile, lockFile, resumeThreshold );
                }
                catch ( IOException e )
                {
                    lockFile.close();
                    LOGGER.debug( "Cannot create resumable file {}: {}", partFile.getAbsolutePath(), e.getMessage(),
                            e );
                    // fall through and try non-resumable/temporary file location
                }
            }

            File tempFile =
                File.createTempFile( dstFile.getName() + '-' + UUID.randomUUID().toString().replace( "-", "" ), ".tmp",
                                     dstFile.getParentFile() );
            return new PartialFile( tempFile );
        }

    }

    private final File partFile;

    private final LockFile lockFile;

    private final long threshold;

    private static final Logger LOGGER = LoggerFactory.getLogger( PartialFile.class );

    private PartialFile( File partFile )
    {
        this( partFile, null, 0L );
    }

    private PartialFile( File partFile, LockFile lockFile, long threshold )
    {
        this.partFile = partFile;
        this.lockFile = lockFile;
        this.threshold = threshold;
    }

    public File getFile()
    {
        return partFile;
    }

    public boolean isResume()
    {
        return lockFile != null && partFile.length() >= threshold;
    }

    public void close() throws IOException
    {
        if ( partFile.exists() && !isResume() )
        {
            if ( !partFile.delete() && partFile.exists() )
            {
                LOGGER.debug( "Could not delete temporary file {}", partFile );
            }
        }
        if ( lockFile != null )
        {
            lockFile.close();
        }
    }

    @Override
    public String toString()
    {
        return String.valueOf( getFile() );
    }

}
