package zip 
{
import com.hurlant.crypto.hash.MD5;
import com.hurlant.util.Hex;
import flash.events.Event;
import flash.events.IOErrorEvent;
import flash.filesystem.File;
import flash.filesystem.FileMode;
import flash.filesystem.FileStream;
import flash.net.URLLoader;
import flash.net.URLLoaderDataFormat;
import flash.net.URLRequest;
import flash.utils.ByteArray;
import deng.fzip.FZip;
import deng.fzip.FZipFile;
import flash.utils.Dictionary;

public class ZIPResourceLoader {
    public var resourcesURL:String = "http://127.0.0.1:8000/resources.zip";
    public var localFilePath:String = File.applicationStorageDirectory.nativePath + File.separator + "resources.zip";
    public var zipLoader:URLLoader = new URLLoader();

    public function ZIPResourceLoader() {
        zipLoader.dataFormat = URLLoaderDataFormat.BINARY;
        zipLoader.addEventListener(Event.COMPLETE, onZipLoaded);
        zipLoader.addEventListener(IOErrorEvent.IO_ERROR, onZipLoadError);
        zipLoader.addEventListener(Event.OPEN, onZipLoadStart);
        zipLoader.load(new URLRequest(resourcesURL));
    }

    public function onZipLoadStart(event:Event):void {
        Alert.showMessage("Load resources.zip started!");
    }

    public function onZipLoaded(event:Event):void {
        var zipBytes:ByteArray = zipLoader.data;
        var fileStream:FileStream = new FileStream();
        fileStream.open(new File(localFilePath), FileMode.WRITE);
        fileStream.writeBytes(zipBytes, 0, zipBytes.length);
        fileStream.close();

        // Проверяем MD5 суммы
        var md5URL:String = "http://127.0.0.1:8000/resources.zip.md5";
		var md5FileName:String = "md5"; // Новая переменная для имени файла MD5
        var md5Loader:URLLoader = new URLLoader();
		var md5LocalFilePath:String = File.applicationStorageDirectory.nativePath + File.separator + md5FileName;
        md5Loader.addEventListener(Event.COMPLETE, function(md5Event:Event):void {
            var md5:String = md5Event.target.data;
            var md5Local:String = calculateMD5(localFilePath);

            if (md5 != md5Local) {
                var zipFile:FZip = new FZip();
                zipFile.addEventListener(Event.COMPLETE, onZipExtracted);
                zipFile.load(new URLRequest(localFilePath));
            } else {
                // Если MD5 суммы совпадают, архив на хосте не изменился
                // Выполните здесь необходимые действия
                Alert.showMessage("Resources.zip has not changed");
            }
        });
        md5Loader.addEventListener(IOErrorEvent.IO_ERROR, function(md5Error:IOErrorEvent):void {
            Alert.showMessage("Failed to load resources.zip.md5" + md5Error.toString());
        });
        md5Loader.load(new URLRequest(md5URL));
    }

    public function onZipLoadError(event:IOErrorEvent):void {
        Alert.showMessage("Failed to load resources.zip");
    }

    public function onZipExtracted(event:Event):void {
        var zipFile:FZip = event.target as FZip;
        try {
            var extractedFiles:Dictionary = new Dictionary();
            
            for (var i:int = 0; i < zipFile.getFileCount(); i++) {
                var zipEntry:FZipFile = zipFile.getFileAt(i);
                var targetFilePath:String = File.applicationStorageDirectory.nativePath + File.separator + "cache/resources" + File.separator + zipEntry.filename;
                var targetFile:File = new File(targetFilePath);
                
                extractedFiles[targetFilePath] = true;
                
                if (zipEntry.filename.charAt(zipEntry.filename.length - 1) == "/") {
                    targetFile.createDirectory();
                } else {
                    var targetFileStream:FileStream = new FileStream();
                    targetFileStream.open(targetFile, FileMode.WRITE);
                    targetFileStream.writeBytes(zipEntry.content);
                    targetFileStream.close();
                }
            }
            
            // Удаляем все файлы, которые не были извлечены из архива
            var cacheDir:File = new File(File.applicationStorageDirectory.nativePath + File.separator + "cache/resources");
            var listCacheDir:Array = cacheDir.getDirectoryListing();
            
            for each (var file:File in listCacheDir) {
                if (!extractedFiles[file.nativePath]) {
                    file.deleteFile();
                }
            }

            Alert.showMessage("Extracted successfully!");
        } catch (error:Error) {
            Alert.showMessage("Failed to extract resources.zip: " + error.message + " (" + error.errorID + ")");
        }
    }
    
    private function calculateMD5(filePath:String):String {
        var file:File = new File(filePath);
        var fileStream:FileStream = new FileStream();
        fileStream.open(file, FileMode.READ);
        var fileBytes:ByteArray = new ByteArray();
        fileStream.readBytes(fileBytes, 0, fileStream.bytesAvailable);
        fileStream.close();
        
        var md5Hash:MD5 = new MD5();
        var hashBytes:ByteArray = md5Hash.hash(fileBytes);
        
        return Hex.fromArray(hashBytes);
    }
}
} мне надо чтобы resources.zip.md5 скачивался в applicationStorageDirectory а потом уже сравнивался с хостом