/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed 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 vogar;

import com.google.common.base.Charsets;

import java.io.File;
import java.io.FileInputStream;
import java.security.MessageDigest;

/**
 * Caches content by MD5.
 */
public final class Md5Cache {

    private final Log log;
    private final String keyPrefix;
    private final FileCache fileCache;

    /**
     * Creates a new cache accessor. There's only one directory on disk, so 'keyPrefix' is really
     * just a convenience for humans inspecting the cache.
     */
    public Md5Cache(Log log, String keyPrefix, FileCache fileCache) {
        this.log = log;
        this.keyPrefix = keyPrefix;
        this.fileCache = fileCache;
    }

    public boolean getFromCache(File output, String key) {
        if (fileCache.existsInCache(key)) {
            fileCache.copyFromCache(key, output);
            return true;
        }
        return false;
    }

    /**
     * Returns an ASCII hex representation of the MD5 of the content of 'file'.
     */
    private static String md5(File file) {
        byte[] digest = null;
        try {
            MessageDigest digester = MessageDigest.getInstance("MD5");
            byte[] bytes = new byte[8192];
            FileInputStream in = new FileInputStream(file);
            try {
                int byteCount;
                while ((byteCount = in.read(bytes)) > 0) {
                    digester.update(bytes, 0, byteCount);
                }
                digest = digester.digest();
            } finally {
                in.close();
            }
        } catch (Exception cause) {
            throw new RuntimeException("Unable to compute MD5 of \"" + file + "\"", cause);
        }
        return (digest == null) ? null : byteArrayToHexString(digest);
    }

    /**
     * Returns an ASCII hex representation of the MD5 of 'string'.
     */
    private static String md5(String string) {
        byte[] digest;
        try {
            MessageDigest digester = MessageDigest.getInstance("MD5");
            digester.update(string.getBytes(Charsets.UTF_8));
            digest = digester.digest();
        } catch (Exception cause) {
            throw new RuntimeException("Unable to compute MD5 of \"" + string + "\"", cause);
        }
        return (digest == null) ? null : byteArrayToHexString(digest);
    }

    private static String byteArrayToHexString(byte[] bytes) {
        StringBuilder result = new StringBuilder();
        for (byte b : bytes) {
            result.append(Integer.toHexString((b >> 4) & 0xf));
            result.append(Integer.toHexString(b & 0xf));
        }
        return result.toString();
    }

    /**
     * Returns the appropriate key for a dex file corresponding to the contents of 'classpath'.
     * Returns null if we don't think it's possible to cache the given classpath.
     */
    public String makeKey(Classpath classpath) {
        // Do we have it in cache?
        String key = keyPrefix;
        for (File element : classpath.getElements()) {
            // We only cache dexed .jar files, not directories.
            String fileName = element.getName();
            if (!fileName.endsWith(".jar")) {
                return null;
            }
            key += "-" + md5(element);
        }
        return key;
    }

    /**
     * Returns a key corresponding to the MD5ed contents of {@code file}.
     */
    public String makeKey(File file) {
        return keyPrefix + "-" + md5(file);
    }

    /**
     * Returns a key corresponding to the MD5ed contents of the element.
     */
    public String makeKey(String... elements) {
        StringBuilder sb = new StringBuilder();
        for (String element : elements) {
          sb.append(element);
          sb.append('|');
        }
        return keyPrefix + "-" + md5(sb.toString());
    }

    /**
     * Copy the file 'content' into the cache with the given 'key'.
     * This method assumes you're using the appropriate key for the content (and has no way to
     * check because the key is a function of the inputs that made the content, not the content
     * itself).
     * We accept a null so the caller doesn't have to pay attention to whether we think we can
     * cache the content or not.
     */
    public void insert(String key, File content) {
        if (key == null) {
            return;
        }
        log.verbose("inserting " + key);
        fileCache.copyToCache(content, key);
    }
}
