/*
 * 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.sidecar.restore;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.util.UUID;
import java.util.concurrent.ThreadLocalRandom;
import java.util.stream.Stream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

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

import com.datastax.driver.core.utils.UUIDs;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import com.google.inject.name.Named;
import org.apache.cassandra.sidecar.exceptions.RestoreJobException;
import org.apache.cassandra.sidecar.exceptions.RestoreJobFatalException;
import org.apache.cassandra.sidecar.utils.DigestAlgorithm;
import org.apache.cassandra.sidecar.utils.DigestAlgorithmProvider;

/**
 * Utilities that only makes sense in the context of restore jobs.
 *
 * Note: Avoid using it in the other scenarios.
 *
 */
@Singleton
public class RestoreJobUtil
{
    private static final Logger LOGGER = LoggerFactory.getLogger(RestoreJobUtil.class);
    private static final int KB_512 = 512 * 1024;
    // it is part of upload id and get validated by
    // org.apache.cassandra.sidecar.utils.SSTableUploadsPathBuilder.UPLOAD_ID_PATTERN
    private static final String RESTORE_JOB_PREFIX = "c0ffee-";
    private static final int RESTORE_JOB_PREFIX_LEN = RESTORE_JOB_PREFIX.length();
    private static final int RESTORE_JOB_DEFAULT_HASH_SEED = 0;

    private final DigestAlgorithmProvider digestAlgorithmProvider;

    @Inject
    public RestoreJobUtil(@Named("xxhash32") DigestAlgorithmProvider digestAlgorithmProvider)
    {
        this.digestAlgorithmProvider = digestAlgorithmProvider;
    }

    /**
     * Unzip a restore slice zip
     * @param zipFile source zip file
     * @param targetDir directory to keep the unzipped files
     * @throws IOException I/O exceptions during unzip
     * @throws RestoreJobException the zip file is malicious
     */
    public static void unzip(File zipFile, File targetDir) throws IOException, RestoreJobException
    {
        try (ZipInputStream zis = new ZipInputStream(Files.newInputStream(zipFile.toPath())))
        {
            ZipEntry zipEntry;

            while ((zipEntry = zis.getNextEntry()) != null)
            {
                // Encounters a directory inside the zip file
                // It is not expected. The zip file should have the directory depth of 1.
                // The reason of not using isDirectory(): in test, it gets 'dir/file' directly, instead of 'dir/'
                if (zipEntry.getName().contains(File.separator))
                {
                    throw new RestoreJobFatalException("Unexpected directory in slice zip file. File: " + zipFile);
                }

                File targetFile = newProtectedTargetFile(zipEntry, targetDir);
                Files.copy(zis, targetFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
            }
            zis.closeEntry();
        }
    }

    /**
     * Resolve a prefixed job id for path
     * @param jobId restore job id
     * @return prefixed job id string
     */
    public static String prefixedJobId(UUID jobId)
    {
        return RESTORE_JOB_PREFIX + jobId;
    }

    public static String generateUniqueUploadId(UUID jobId, String sliceId)
    {
        return prefixedJobId(jobId) + '-' + sliceId + '-' + ThreadLocalRandom.current().nextInt(10000);
    }

    /**
     * Extract the timestamp from the restore job directory name.
     * @param fileName directory file name
     * @return unix timestamp epoch; otherwise, return -1 if no timestamp can be extracted
     */
    public static long timestampFromRestoreJobDir(String fileName)
    {
        if (!fileName.startsWith(RESTORE_JOB_PREFIX))
            return -1;

        try
        {
            UUID id = UUID.fromString(fileName.substring(RESTORE_JOB_PREFIX_LEN));
            return UUIDs.unixTimestamp(id);
        }
        catch (IllegalArgumentException e)
        {
            return -1;
        }
    }

    /**
     * Cleans given directory path without deleting it
     * @param path directory path to be cleaned
     * @throws IOException when I/O error occurs
     */
    public static void cleanDirectory(Path path) throws IOException
    {
        if (!Files.isDirectory(path) || !Files.exists(path))
        {
            LOGGER.warn("Clean directory API called for non existent directory: {}", path);
            return;
        }

        try (Stream<Path> contents = Files.list(path))
        {
            contents.forEach(filePath -> {
                try
                {
                    if (Files.isDirectory(filePath))
                    {
                        cleanDirectory(filePath);
                    }
                    Files.delete(filePath);
                }
                catch (IOException e)
                {
                    LOGGER.error("Unexpected error occurred while cleaning directory {}", path, e);
                    throw new RuntimeException(e);
                }
            });
        }
    }

    /**
     * Create a file that is protected from zip slip attack (https://security.snyk.io/research/zip-slip-vulnerability)
     * @param zipEntry zip entry to be extracted
     * @param targetDir directory to keep the unzipped files
     * @return a new file
     * @throws IOException failed to resolving path
     * @throws RestoreJobException if the zip file is malicious
     */
    private static File newProtectedTargetFile(ZipEntry zipEntry, File targetDir)
    throws IOException, RestoreJobException
    {
        File targetFile = new File(targetDir, zipEntry.getName());

        // Normalize the paths of both target dir and file
        String targetDirPath = targetDir.getCanonicalPath();
        String targetFilePath = targetFile.getCanonicalPath();

        if (!targetFilePath.startsWith(targetDirPath))
        {
            throw new RestoreJobException("Bad zip entry: " + zipEntry.getName());
        }

        return targetFile;
    }

    /**
     * @param file the file to use to perform the checksum
     * @return the checksum hex string of the file's content. XXHash32 is employed as the hash algorithm.
     */
    public String checksum(File file) throws IOException
    {
        return checksum(file, RESTORE_JOB_DEFAULT_HASH_SEED);
    }

    /**
     * @param file the file to use to perform the checksum
     * @param seed the seed to use for the hasher
     * @return the checksum hex string of the file's content. XXHash32 is employed as the hash algorithm.
     */
    public String checksum(File file, int seed) throws IOException
    {
        try (InputStream fis = Files.newInputStream(file.toPath()))
        {
            try (DigestAlgorithm digestAlgorithm = digestAlgorithmProvider.get(seed))
            {
                byte[] buffer = new byte[KB_512];
                int len;
                while ((len = fis.read(buffer)) != -1)
                {
                    digestAlgorithm.update(buffer, 0, len);
                }
                return digestAlgorithm.digest();
            }
        }
    }

    /**
     * @return the current time in nanoseconds
     */
    public long currentTimeNanos()
    {
        return System.nanoTime();
    }
}
