// 
// Decompiled by Procyon v0.6.0
// 

package com.hypixel.hytale.server.core.asset.common;

import java.util.concurrent.ConcurrentHashMap;
import io.netty.buffer.ByteBuf;
import com.hypixel.hytale.common.util.CompletableFutureUtil;
import io.netty.buffer.Unpooled;
import javax.annotation.Nullable;
import javax.annotation.Nonnull;
import java.util.concurrent.CompletableFuture;
import java.util.Map;
import com.hypixel.hytale.logger.HytaleLogger;

public class OggVorbisInfoCache
{
    public static final HytaleLogger LOGGER;
    private static final Map<String, OggVorbisInfo> vorbisFiles;
    
    @Nonnull
    public static CompletableFuture<OggVorbisInfo> get(final String name) {
        final OggVorbisInfo info = OggVorbisInfoCache.vorbisFiles.get(name);
        if (info != null) {
            return CompletableFuture.completedFuture(info);
        }
        final CommonAsset asset = CommonAssetRegistry.getByName(name);
        if (asset == null) {
            return CompletableFuture.completedFuture((OggVorbisInfo)null);
        }
        return get0(asset);
    }
    
    @Nonnull
    public static CompletableFuture<OggVorbisInfo> get(@Nonnull final CommonAsset asset) {
        final OggVorbisInfo info = OggVorbisInfoCache.vorbisFiles.get(asset.getName());
        if (info != null) {
            return CompletableFuture.completedFuture(info);
        }
        return get0(asset);
    }
    
    @Nullable
    public static OggVorbisInfo getNow(final String name) {
        final OggVorbisInfo info = OggVorbisInfoCache.vorbisFiles.get(name);
        if (info != null) {
            return info;
        }
        final CommonAsset asset = CommonAssetRegistry.getByName(name);
        if (asset == null) {
            return null;
        }
        return get0(asset).join();
    }
    
    public static OggVorbisInfo getNow(@Nonnull final CommonAsset asset) {
        final OggVorbisInfo info = OggVorbisInfoCache.vorbisFiles.get(asset.getName());
        if (info != null) {
            return info;
        }
        return get0(asset).join();
    }
    
    @Nonnull
    private static CompletableFuture<OggVorbisInfo> get0(@Nonnull final CommonAsset asset) {
        final String name = asset.getName();
        return CompletableFutureUtil._catch(asset.getBlob().thenApply(bytes -> {
            final ByteBuf b = Unpooled.wrappedBuffer(bytes);
            try {
                final int len = b.readableBytes();
                int id = -1;
                int i = 0;
                final int end = len - 7;
                while (i <= end) {
                    i = b.indexOf(i, len - 7, (byte)1);
                    if (i == -1) {
                        break;
                    }
                    else if (b.getByte(i + 1) == 118 && b.getByte(i + 2) == 111 && b.getByte(i + 3) == 114 && b.getByte(i + 4) == 98 && b.getByte(i + 5) == 105 && b.getByte(i + 6) == 115) {
                        id = i;
                        break;
                    }
                    else {
                        ++i;
                    }
                }
                if (id < 0 || id + 16 > len) {
                    throw new IllegalArgumentException("Vorbis id header not found");
                }
                else {
                    final int channels = b.getUnsignedByte(id + 11);
                    final int sampleRate = b.getIntLE(id + 12);
                    double duration = -1.0;
                    if (sampleRate > 0) {
                        int j = Math.max(0, len - 14);
                        while (j >= 0) {
                            j = b.indexOf(j, 0, (byte)79);
                            if (j == -1) {
                                break;
                            }
                            else {
                                if (b.getByte(j + 1) == 103 && b.getByte(j + 2) == 103 && b.getByte(j + 3) == 83) {
                                    final int headerType = b.getUnsignedByte(j + 5);
                                    if ((headerType & 0x4) != 0x0) {
                                        final long granule = b.getLongLE(j + 6);
                                        if (granule >= 0L) {
                                            duration = granule / (double)sampleRate;
                                            break;
                                        }
                                        else {
                                            break;
                                        }
                                    }
                                }
                                --j;
                            }
                        }
                    }
                    final OggVorbisInfo info = new OggVorbisInfo(channels, sampleRate, duration);
                    OggVorbisInfoCache.vorbisFiles.put(name, info);
                    return info;
                }
            }
            finally {
                b.release();
            }
        }));
    }
    
    public static void invalidate(final String name) {
        OggVorbisInfoCache.vorbisFiles.remove(name);
    }
    
    static {
        LOGGER = HytaleLogger.forEnclosingClass();
        vorbisFiles = new ConcurrentHashMap<String, OggVorbisInfo>();
    }
    
    public static class OggVorbisInfo
    {
        public final int channels;
        public final int sampleRate;
        public final double duration;
        
        OggVorbisInfo(final int channels, final int sampleRate, final double duration) {
            this.channels = channels;
            this.sampleRate = sampleRate;
            this.duration = duration;
        }
        
        @Nonnull
        @Override
        public String toString() {
            return "OggVorbisInfo{channels=" + this.channels + ", sampleRate=" + this.sampleRate + ", duration=" + this.duration;
        }
    }
}
