package org.apache.archiva.checksum;

/*
 * 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.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.StandardOpenOption;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * ChecksummedFile
 * <p>Terminology:</p>
 * <dl>
 * <dt>Checksum File</dt>
 * <dd>The file that contains the previously calculated checksum value for the reference file.
 * This is a text file with the extension ".sha1" or ".md5", and contains a single entry
 * consisting of an optional reference filename, and a checksum string.
 * </dd>
 * <dt>Reference File</dt>
 * <dd>The file that is being referenced in the checksum file.</dd>
 * </dl>
 */
public class ChecksummedFile
{
    private final Logger log = LoggerFactory.getLogger( ChecksummedFile.class );

    private static final Pattern METADATA_PATTERN = Pattern.compile( "maven-metadata-\\S*.xml" );

    private final File referenceFile;

    /**
     * Construct a ChecksummedFile object.
     *
     * @param referenceFile
     */
    public ChecksummedFile( final File referenceFile )
    {
        this.referenceFile = referenceFile;
    }

    /**
     * Calculate the checksum based on a given checksum.
     *
     * @param checksumAlgorithm the algorithm to use.
     * @return the checksum string for the file.
     * @throws IOException if unable to calculate the checksum.
     */
    public String calculateChecksum( ChecksumAlgorithm checksumAlgorithm )
        throws IOException
    {

        try (InputStream fis = Files.newInputStream( referenceFile.toPath() ))
        {
            Checksum checksum = new Checksum( checksumAlgorithm );
            checksum.update( fis );
            return checksum.getChecksum();
        }
    }

    /**
     * Creates a checksum file of the provided referenceFile.
     *
     * @param checksumAlgorithm the hash to use.
     * @return the checksum File that was created.
     * @throws IOException if there was a problem either reading the referenceFile, or writing the checksum file.
     */
    public File createChecksum( ChecksumAlgorithm checksumAlgorithm )
        throws IOException
    {
        File checksumFile = new File( referenceFile.getAbsolutePath() + "." + checksumAlgorithm.getExt() );
        Files.deleteIfExists( checksumFile.toPath() );
        String checksum = calculateChecksum( checksumAlgorithm );
        Files.write( checksumFile.toPath(), //
                     ( checksum + "  " + referenceFile.getName() ).getBytes(), //
                     StandardOpenOption.CREATE_NEW );
        return checksumFile;
    }

    /**
     * Get the checksum file for the reference file and hash.
     *
     * @param checksumAlgorithm the hash that we are interested in.
     * @return the checksum file to return
     */
    public File getChecksumFile( ChecksumAlgorithm checksumAlgorithm )
    {
        return new File( referenceFile.getAbsolutePath() + "." + checksumAlgorithm.getExt() );
    }

    /**
     * <p>
     * Given a checksum file, check to see if the file it represents is valid according to the checksum.
     * </p>
     * <p>
     * NOTE: Only supports single file checksums of type MD5 or SHA1.
     * </p>
     *
     * @param algorithm the algorithms to check for.
     * @return true if the checksum is valid for the file it represents. or if the checksum file does not exist.
     * @throws IOException if the reading of the checksumFile or the file it refers to fails.
     */
    public boolean isValidChecksum( ChecksumAlgorithm algorithm )
        throws IOException
    {
        return isValidChecksums( new ChecksumAlgorithm[]{ algorithm } );
    }

    /**
     * Of any checksum files present, validate that the reference file conforms
     * the to the checksum.
     *
     * @param algorithms the algorithms to check for.
     * @return true if the checksums report that the the reference file is valid, false if invalid.
     */
    public boolean isValidChecksums( ChecksumAlgorithm algorithms[] )
    {

        try (InputStream fis = Files.newInputStream( referenceFile.toPath() ))
        {
            List<Checksum> checksums = new ArrayList<>( algorithms.length );
            // Create checksum object for each algorithm.
            for ( ChecksumAlgorithm checksumAlgorithm : algorithms )
            {
                File checksumFile = getChecksumFile( checksumAlgorithm );

                // Only add algorithm if checksum file exists.
                if ( checksumFile.exists() )
                {
                    checksums.add( new Checksum( checksumAlgorithm ) );
                }
            }

            // Any checksums?
            if ( checksums.isEmpty() )
            {
                // No checksum objects, no checksum files, default to is invalid.
                return false;
            }

            // Parse file once, for all checksums.
            try
            {
                Checksum.update( checksums, fis );
            }
            catch ( IOException e )
            {
                log.warn( "Unable to update checksum:{}", e.getMessage() );
                return false;
            }

            boolean valid = true;

            // check the checksum files
            try
            {
                for ( Checksum checksum : checksums )
                {
                    ChecksumAlgorithm checksumAlgorithm = checksum.getAlgorithm();
                    File checksumFile = getChecksumFile( checksumAlgorithm );

                    String rawChecksum = FileUtils.readFileToString( checksumFile );
                    String expectedChecksum = parseChecksum( rawChecksum, checksumAlgorithm, referenceFile.getName() );

                    if ( !StringUtils.equalsIgnoreCase( expectedChecksum, checksum.getChecksum() ) )
                    {
                        valid = false;
                    }
                }
            }
            catch ( IOException e )
            {
                log.warn( "Unable to read / parse checksum: {}", e.getMessage() );
                return false;
            }

            return valid;
        }
        catch ( IOException e )
        {
            log.warn( "Unable to read / parse checksum: {}", e.getMessage() );
            return false;
        }
    }

    /**
     * Fix or create checksum files for the reference file.
     *
     * @param algorithms the hashes to check for.
     * @return true if checksums were created successfully.
     */
    public boolean fixChecksums( ChecksumAlgorithm[] algorithms )
    {
        List<Checksum> checksums = new ArrayList<>( algorithms.length );
        // Create checksum object for each algorithm.
        for ( ChecksumAlgorithm checksumAlgorithm : algorithms )
        {
            checksums.add( new Checksum( checksumAlgorithm ) );
        }

        // Any checksums?
        if ( checksums.isEmpty() )
        {
            // No checksum objects, no checksum files, default to is valid.
            return true;
        }

        try (InputStream fis = Files.newInputStream( referenceFile.toPath() ))
        {
            // Parse file once, for all checksums.
            Checksum.update( checksums, fis );
        }
        catch ( IOException e )
        {
            log.warn( e.getMessage(), e );
            return false;
        }

        boolean valid = true;

        // check the hash files
        for ( Checksum checksum : checksums )
        {
            ChecksumAlgorithm checksumAlgorithm = checksum.getAlgorithm();
            try
            {
                File checksumFile = getChecksumFile( checksumAlgorithm );
                String actualChecksum = checksum.getChecksum();

                if ( checksumFile.exists() )
                {
                    String rawChecksum = FileUtils.readFileToString( checksumFile );
                    String expectedChecksum = parseChecksum( rawChecksum, checksumAlgorithm, referenceFile.getName() );

                    if ( !StringUtils.equalsIgnoreCase( expectedChecksum, actualChecksum ) )
                    {
                        // create checksum (again)
                        FileUtils.writeStringToFile( checksumFile, actualChecksum + "  " + referenceFile.getName() );
                    }
                }
                else
                {
                    FileUtils.writeStringToFile( checksumFile, actualChecksum + "  " + referenceFile.getName() );
                }
            }
            catch ( IOException e )
            {
                log.warn( e.getMessage(), e );
                valid = false;
            }
        }

        return valid;

    }

    private boolean isValidChecksumPattern( String filename, String path )
    {
        // check if it is a remote metadata file

        Matcher m = METADATA_PATTERN.matcher( path );
        if ( m.matches() )
        {
            return filename.endsWith( path ) || ( "-".equals( filename ) ) || filename.endsWith( "maven-metadata.xml" );
        }

        return filename.endsWith( path ) || ( "-".equals( filename ) );
    }

    /**
     * Parse a checksum string.
     * <p>
     * Validate the expected path, and expected checksum algorithm, then return
     * the trimmed checksum hex string.
     * </p>
     *
     * @param rawChecksumString
     * @param expectedHash
     * @param expectedPath
     * @return
     * @throws IOException
     */
    public String parseChecksum( String rawChecksumString, ChecksumAlgorithm expectedHash, String expectedPath )
        throws IOException
    {
        String trimmedChecksum = rawChecksumString.replace( '\n', ' ' ).trim();

        // Free-BSD / openssl
        String regex = expectedHash.getType() + "\\s*\\(([^)]*)\\)\\s*=\\s*([a-fA-F0-9]+)";
        Matcher m = Pattern.compile( regex ).matcher( trimmedChecksum );
        if ( m.matches() )
        {
            String filename = m.group( 1 );
            if ( !isValidChecksumPattern( filename, expectedPath ) )
            {
                throw new IOException(
                    "Supplied checksum file '" + filename + "' does not match expected file: '" + expectedPath + "'" );
            }
            trimmedChecksum = m.group( 2 );
        }
        else
        {
            // GNU tools
            m = Pattern.compile( "([a-fA-F0-9]+)\\s+\\*?(.+)" ).matcher( trimmedChecksum );
            if ( m.matches() )
            {
                String filename = m.group( 2 );
                if ( !isValidChecksumPattern( filename, expectedPath ) )
                {
                    throw new IOException(
                        "Supplied checksum file '" + filename + "' does not match expected file: '" + expectedPath
                            + "'" );
                }
                trimmedChecksum = m.group( 1 );
            }
        }
        return trimmedChecksum;
    }
}
