package mapped;

import com.google.common.hash.Hashing;
import com.google.common.io.ByteStreams;
import com.google.common.io.CharStreams;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import net.runelite.api.overlay.OverlayIndex;
import net.runelite.mapping.ObfuscatedGetter;
import net.runelite.mapping.ObfuscatedName;
import net.runelite.mapping.ObfuscatedSignature;
import net.runelite.rs.api.RSAbstractArchive;
import net.runelite.rs.api.RSArchive;
import org.slf4j.Logger;

@ObfuscatedName("ol")
public abstract class AbstractArchive implements RSAbstractArchive {
   @ObfuscatedName("bf")
   @ObfuscatedSignature(
      descriptor = "Lve;"
   )
   static GZipDecompressor gzipDecompressor;
   @ObfuscatedName("bp")
   @ObfuscatedGetter(
      intValue = 170709657
   )
   static int field4303;
   @ObfuscatedName("ai")
   @ObfuscatedGetter(
      intValue = -121591717
   )
   int groupCount;
   @ObfuscatedName("aw")
   int[] groupIds;
   @ObfuscatedName("ae")
   int[] groupNameHashes;
   @ObfuscatedName("an")
   @ObfuscatedSignature(
      descriptor = "Lvh;"
   )
   IntHashTable groupNameHashTable;
   @ObfuscatedName("ag")
   int[] groupCrcs;
   @ObfuscatedName("ad")
   int[] groupVersions;
   @ObfuscatedName("af")
   int[] fileCounts;
   @ObfuscatedName("be")
   int[][] fileIds;
   @ObfuscatedName("bd")
   int[][] fileNameHashes;
   @ObfuscatedName("bl")
   @ObfuscatedSignature(
      descriptor = "[Lvh;"
   )
   IntHashTable[] fileNameHashTables;
   @ObfuscatedName("bi")
   Object[] groups;
   @ObfuscatedName("bv")
   Object[][] files;
   @ObfuscatedName("bg")
   @ObfuscatedGetter(
      intValue = 1759179805
   )
   public int hash;
   @ObfuscatedName("ba")
   boolean releaseGroups;
   @ObfuscatedName("bm")
   boolean shallowFiles;
   public boolean overlayOutdated;

   static {
      gzipDecompressor = new GZipDecompressor();
      field4303 = 0;
   }

   AbstractArchive(boolean var1, boolean var2) {
      this.releaseGroups = var1;
      this.shallowFiles = var2;
   }

   @ObfuscatedName("ar")
   @ObfuscatedSignature(
      descriptor = "(II)V",
      garbageValue = "606874642"
   )
   void loadRegionFromGroup_base(int var1) {
   }

   @ObfuscatedName("ao")
   @ObfuscatedSignature(
      descriptor = "(II)V",
      garbageValue = "-412384319"
   )
   void loadGroup_base(int var1) {
   }

   @ObfuscatedName("az")
   @ObfuscatedSignature(
      descriptor = "(II)I",
      garbageValue = "-788412100"
   )
   int groupLoadPercent_base(int var1) {
      return this.groups[var1] != null?100:0;
   }

   @ObfuscatedName("bq")
   @ObfuscatedSignature(
      descriptor = "([BI)V",
      garbageValue = "-18383412"
   )
   void decodeIndex_base(byte[] var1) {
      int var3 = var1.length;
      int var2 = class174.method3540_base(var1, 0, var3);
      this.hash = var2;
      Buffer var4 = new Buffer(class30.decompressBytes_base(var1));
      int var5 = var4.readUnsignedByte_base();
      if(var5 >= 5 && var5 <= 7) {
         if(var5 >= 6) {
            var4.readInt_base();
         }

         int var6 = var4.readUnsignedByte_base();
         if(var5 >= 7) {
            this.groupCount = var4.readLargeSmart_base();
         } else {
            this.groupCount = var4.readUnsignedShort_base();
         }

         int var7 = 0;
         int var8 = -1;
         this.groupIds = new int[this.groupCount];
         int var9;
         if(var5 >= 7) {
            for(var9 = 0; var9 < this.groupCount; ++var9) {
               this.groupIds[var9] = var7 += var4.readLargeSmart_base();
               if(this.groupIds[var9] > var8) {
                  var8 = this.groupIds[var9];
               }
            }
         } else {
            for(var9 = 0; var9 < this.groupCount; ++var9) {
               this.groupIds[var9] = var7 += var4.readUnsignedShort_base();
               if(this.groupIds[var9] > var8) {
                  var8 = this.groupIds[var9];
               }
            }
         }

         this.groupCrcs = new int[var8 + 1];
         this.groupVersions = new int[var8 + 1];
         this.fileCounts = new int[var8 + 1];
         this.fileIds = new int[var8 + 1][];
         this.groups = new Object[var8 + 1];
         this.files = new Object[var8 + 1][];
         if(var6 != 0) {
            this.groupNameHashes = new int[var8 + 1];

            for(var9 = 0; var9 < this.groupCount; ++var9) {
               this.groupNameHashes[this.groupIds[var9]] = var4.readInt_base();
            }

            this.groupNameHashTable = new IntHashTable(this.groupNameHashes);
         }

         for(var9 = 0; var9 < this.groupCount; ++var9) {
            this.groupCrcs[this.groupIds[var9]] = var4.readInt_base();
         }

         for(var9 = 0; var9 < this.groupCount; ++var9) {
            this.groupVersions[this.groupIds[var9]] = var4.readInt_base();
         }

         for(var9 = 0; var9 < this.groupCount; ++var9) {
            this.fileCounts[this.groupIds[var9]] = var4.readUnsignedShort_base();
         }

         int var10;
         int var11;
         int var12;
         int var13;
         int var14;
         if(var5 >= 7) {
            for(var9 = 0; var9 < this.groupCount; ++var9) {
               var10 = this.groupIds[var9];
               var11 = this.fileCounts[var10];
               var7 = 0;
               var12 = -1;
               this.fileIds[var10] = new int[var11];

               for(var13 = 0; var13 < var11; ++var13) {
                  var14 = this.fileIds[var10][var13] = var7 += var4.readLargeSmart_base();
                  if(var14 > var12) {
                     var12 = var14;
                  }
               }

               this.files[var10] = new Object[var12 + 1];
            }
         } else {
            for(var9 = 0; var9 < this.groupCount; ++var9) {
               var10 = this.groupIds[var9];
               var11 = this.fileCounts[var10];
               var7 = 0;
               var12 = -1;
               this.fileIds[var10] = new int[var11];

               for(var13 = 0; var13 < var11; ++var13) {
                  var14 = this.fileIds[var10][var13] = var7 += var4.readUnsignedShort_base();
                  if(var14 > var12) {
                     var12 = var14;
                  }
               }

               this.files[var10] = new Object[var12 + 1];
            }
         }

         if(var6 != 0) {
            this.fileNameHashes = new int[var8 + 1][];
            this.fileNameHashTables = new IntHashTable[var8 + 1];

            for(var9 = 0; var9 < this.groupCount; ++var9) {
               var10 = this.groupIds[var9];
               var11 = this.fileCounts[var10];
               this.fileNameHashes[var10] = new int[this.files[var10].length];

               for(var12 = 0; var12 < var11; ++var12) {
                  this.fileNameHashes[var10][this.fileIds[var10][var12]] = var4.readInt_base();
               }

               this.fileNameHashTables[var10] = new IntHashTable(this.fileNameHashes[var10]);
            }
         }

      } else {
         throw new RuntimeException("");
      }
   }

   @ObfuscatedName("cf")
   @ObfuscatedSignature(
      descriptor = "(III)[B",
      garbageValue = "882307207"
   )
   public byte[] takeFile_base(int var1, int var2) {
      byte[] var3 = this.copy$takeFile(var1, var2, 946380186);
      int var4 = ((RSArchive)this).getIndex();
      if(OverlayIndex.hasCacheTransformer(var4, var1)) {
         return (byte[])OverlayIndex.getCacheTransformer(var4, var1).apply(var3);
      } else if(!OverlayIndex.hasOverlay(var4, var1)) {
         return var3;
      } else {
         Logger var5 = SpriteMask.client.getLogger();
         String var6 = String.format("/runelite/%s/%s", new Object[]{Integer.valueOf(var4), Integer.valueOf(var1)});
         if(var3 != null) {
            String var7;
            String var8;
            try {
               InputStream var9 = this.getClass().getResourceAsStream(var6 + ".hash");

               try {
                  var7 = CharStreams.toString(new InputStreamReader(var9));
                  var8 = Hashing.sha256().hashBytes(var3).toString();
               } catch (Throwable var14) {
                  if(var9 != null) {
                     try {
                        var9.close();
                     } catch (Throwable var12) {
                        var14.addSuppressed(var12);
                     }
                  }

                  throw var14;
               }

               if(var9 != null) {
                  var9.close();
               }
            } catch (IOException var17) {
               var5.warn("Missing overlay hash for {}/{}", Integer.valueOf(var4), Integer.valueOf(var1));
               return var3;
            }

            if(!var7.equalsIgnoreCase(var8)) {
               var5.error("Script " + var1 + " is invalid, and will not be overlaid. This will break plugin(s)!");
               this.overlayOutdated = true;
               return var3;
            }
         }

         if(Client.customClientScripts.containsKey(Integer.valueOf(var4 << 16 | var1))) {
            return (byte[])Client.customClientScripts.get(Integer.valueOf(var4 << 16 | var1));
         } else {
            byte[] var19;
            try {
               InputStream var18 = this.getClass().getResourceAsStream(var6);

               try {
                  var19 = ByteStreams.toByteArray(var18);
               } catch (Throwable var15) {
                  if(var18 != null) {
                     try {
                        var18.close();
                     } catch (Throwable var13) {
                        var15.addSuppressed(var13);
                     }
                  }

                  throw var15;
               }

               if(var18 != null) {
                  var18.close();
               }
            } catch (IOException var16) {
               var5.warn("Missing overlay data for {}/{}", Integer.valueOf(var4), Integer.valueOf(var1));
               return var3;
            }

            return var19;
         }
      }
   }

   @ObfuscatedName("cg")
   @ObfuscatedSignature(
      descriptor = "(II[II)[B",
      garbageValue = "1812200763"
   )
   public byte[] takeFileEncrypted_base(int var1, int var2, int[] var3) {
      if(var1 >= 0 && var1 < this.files.length && this.files[var1] != null && var2 >= 0 && var2 < this.files[var1].length) {
         if(this.files[var1][var2] == null) {
            boolean var4 = this.buildFiles_base(var1, var3);
            if(!var4) {
               this.loadGroup_base(var1);
               var4 = this.buildFiles_base(var1, var3);
               if(!var4) {
                  return null;
               }
            }
         }

         byte[] var5 = class128.method3079_base(this.files[var1][var2], false);
         if(this.shallowFiles) {
            this.files[var1][var2] = null;
         }

         return var5;
      } else {
         return null;
      }
   }

   @ObfuscatedName("cv")
   @ObfuscatedSignature(
      descriptor = "(III)Z",
      garbageValue = "-641449035"
   )
   public boolean tryLoadFile_base(int var1, int var2) {
      if(var1 >= 0 && var1 < this.files.length && this.files[var1] != null && var2 >= 0 && var2 < this.files[var1].length) {
         if(this.files[var1][var2] != null) {
            return true;
         } else if(this.groups[var1] != null) {
            return true;
         } else {
            this.loadGroup_base(var1);
            return this.groups[var1] != null;
         }
      } else {
         return false;
      }
   }

   @ObfuscatedName("cx")
   @ObfuscatedSignature(
      descriptor = "(II)Z",
      garbageValue = "-544854529"
   )
   public boolean method6954_base(int var1) {
      if(this.files.length == 1) {
         return this.tryLoadFile_base(0, var1);
      } else if(this.files[var1].length == 1) {
         return this.tryLoadFile_base(var1, 0);
      } else {
         throw new RuntimeException();
      }
   }

   @ObfuscatedName("cp")
   @ObfuscatedSignature(
      descriptor = "(II)Z",
      garbageValue = "456199859"
   )
   public boolean tryLoadGroup_base(int var1) {
      if(this.groups[var1] != null) {
         return true;
      } else {
         this.loadGroup_base(var1);
         return this.groups[var1] != null;
      }
   }

   @ObfuscatedName("ce")
   @ObfuscatedSignature(
      descriptor = "(B)Z",
      garbageValue = "127"
   )
   public boolean isFullyLoaded_base() {
      boolean var1 = true;

      for(int var2 = 0; var2 < this.groupIds.length; ++var2) {
         int var3 = this.groupIds[var2];
         if(this.groups[var3] == null) {
            this.loadGroup_base(var3);
            if(this.groups[var3] == null) {
               var1 = false;
            }
         }
      }

      return var1;
   }

   @ObfuscatedName("ci")
   @ObfuscatedSignature(
      descriptor = "(IB)[B",
      garbageValue = "-56"
   )
   public byte[] takeFileFlat_base(int var1) {
      if(this.files.length == 1) {
         return this.takeFile_base(0, var1);
      } else if(this.files[var1].length == 1) {
         return this.takeFile_base(var1, 0);
      } else {
         throw new RuntimeException();
      }
   }

   @ObfuscatedName("ct")
   @ObfuscatedSignature(
      descriptor = "(IIB)[B",
      garbageValue = "-4"
   )
   public byte[] getFile_base(int var1, int var2) {
      if(var1 >= 0 && var1 < this.files.length && this.files[var1] != null && var2 >= 0 && var2 < this.files[var1].length) {
         if(this.files[var1][var2] == null) {
            boolean var3 = this.buildFiles_base(var1, (int[])null);
            if(!var3) {
               this.loadGroup_base(var1);
               var3 = this.buildFiles_base(var1, (int[])null);
               if(!var3) {
                  return null;
               }
            }
         }

         byte[] var4 = class128.method3079_base(this.files[var1][var2], false);
         return var4;
      } else {
         return null;
      }
   }

   @ObfuscatedName("cw")
   @ObfuscatedSignature(
      descriptor = "(II)[B",
      garbageValue = "-1549556992"
   )
   public byte[] getFileFlat_base(int var1) {
      if(this.files.length == 1) {
         return this.getFile_base(0, var1);
      } else if(this.files[var1].length == 1) {
         return this.getFile_base(var1, 0);
      } else {
         throw new RuntimeException();
      }
   }

   @ObfuscatedName("cq")
   @ObfuscatedSignature(
      descriptor = "(II)[I",
      garbageValue = "1026301706"
   )
   public int[] getGroupFileIds_base(int var1) {
      return var1 >= 0 && var1 < this.fileIds.length?this.fileIds[var1]:null;
   }

   @ObfuscatedName("cl")
   @ObfuscatedSignature(
      descriptor = "(II)I",
      garbageValue = "1471865818"
   )
   public int getGroupFileCount_base(int var1) {
      return this.files != null && var1 < this.files.length && this.files[var1] != null?this.files[var1].length:0;
   }

   @ObfuscatedName("cs")
   @ObfuscatedSignature(
      descriptor = "(I)I",
      garbageValue = "1806746664"
   )
   public int getGroupCount_base() {
      return this.files.length;
   }

   @ObfuscatedName("co")
   @ObfuscatedSignature(
      descriptor = "(B)V",
      garbageValue = "5"
   )
   public void clearGroups_base() {
      for(int var1 = 0; var1 < this.groups.length; ++var1) {
         this.groups[var1] = null;
      }

   }

   @ObfuscatedName("cm")
   @ObfuscatedSignature(
      descriptor = "(II)V",
      garbageValue = "2080028111"
   )
   public void clearFilesGroup_base(int var1) {
      for(int var2 = 0; var2 < this.files[var1].length; ++var2) {
         this.files[var1][var2] = null;
      }

   }

   @ObfuscatedName("cn")
   @ObfuscatedSignature(
      descriptor = "(B)V",
      garbageValue = "6"
   )
   public void clearFiles_base() {
      for(int var1 = 0; var1 < this.files.length; ++var1) {
         if(this.files[var1] != null) {
            for(int var2 = 0; var2 < this.files[var1].length; ++var2) {
               this.files[var1][var2] = null;
            }
         }
      }

   }

   @ObfuscatedName("cr")
   @ObfuscatedSignature(
      descriptor = "(I[IB)Z",
      garbageValue = "19"
   )
   boolean buildFiles_base(int var1, int[] var2) {
      if(this.groups[var1] == null) {
         return false;
      } else {
         int var3 = this.fileCounts[var1];
         int[] var4 = this.fileIds[var1];
         Object[] var5 = this.files[var1];
         boolean var6 = true;

         for(int var7 = 0; var7 < var3; ++var7) {
            if(var5[var4[var7]] == null) {
               var6 = false;
               break;
            }
         }

         if(var6) {
            return true;
         } else {
            byte[] var18;
            if(var2 == null || var2[0] == 0 && var2[1] == 0 && var2[2] == 0 && var2[3] == 0) {
               var18 = class128.method3079_base(this.groups[var1], false);
            } else {
               var18 = class128.method3079_base(this.groups[var1], true);
               Buffer var8 = new Buffer(var18);
               var8.xteaDecrypt_base(var2, 5, var8.array.length);
            }

            byte[] var20 = class30.decompressBytes_base(var18);
            if(this.releaseGroups) {
               this.groups[var1] = null;
            }

            if(var3 > 1) {
               int var9 = var20.length;
               --var9;
               int var10 = var20[var9] & 255;
               var9 -= var3 * var10 * 4;
               Buffer var11 = new Buffer(var20);
               int[] var12 = new int[var3];
               var11.offset = var9;

               int var14;
               int var15;
               for(int var13 = 0; var13 < var10; ++var13) {
                  var14 = 0;

                  for(var15 = 0; var15 < var3; ++var15) {
                     var14 += var11.readInt_base();
                     var12[var15] += var14;
                  }
               }

               byte[][] var19 = new byte[var3][];

               for(var14 = 0; var14 < var3; ++var14) {
                  var19[var14] = new byte[var12[var14]];
                  var12[var14] = 0;
               }

               var11.offset = var9;
               var14 = 0;

               for(var15 = 0; var15 < var10; ++var15) {
                  int var16 = 0;

                  for(int var17 = 0; var17 < var3; ++var17) {
                     var16 += var11.readInt_base();
                     System.arraycopy(var20, var14, var19[var17], var12[var17], var16);
                     var12[var17] += var16;
                     var14 += var16;
                  }
               }

               for(var15 = 0; var15 < var3; ++var15) {
                  if(!this.shallowFiles) {
                     var5[var4[var15]] = VarcInt.method3598_base(var19[var15], false);
                  } else {
                     var5[var4[var15]] = var19[var15];
                  }
               }
            } else if(!this.shallowFiles) {
               var5[var4[0]] = VarcInt.method3598_base(var20, false);
            } else {
               var5[var4[0]] = var20;
            }

            return true;
         }
      }
   }

   @ObfuscatedName("cj")
   @ObfuscatedSignature(
      descriptor = "(Ljava/lang/String;I)I",
      garbageValue = "1994511347"
   )
   public int getGroupId_base(String var1) {
      var1 = var1.toLowerCase();
      return this.groupNameHashTable.get_base(class150.hashString_base(var1));
   }

   @ObfuscatedName("ca")
   @ObfuscatedSignature(
      descriptor = "(ILjava/lang/String;I)I",
      garbageValue = "-1256409998"
   )
   public int getFileId_base(int var1, String var2) {
      var2 = var2.toLowerCase();
      return this.fileNameHashTables[var1].get_base(class150.hashString_base(var2));
   }

   @ObfuscatedName("cc")
   @ObfuscatedSignature(
      descriptor = "(Ljava/lang/String;Ljava/lang/String;S)Z",
      garbageValue = "245"
   )
   public boolean isValidFileName_base(String var1, String var2) {
      var1 = var1.toLowerCase();
      var2 = var2.toLowerCase();
      int var3 = this.groupNameHashTable.get_base(class150.hashString_base(var1));
      if(var3 < 0) {
         return false;
      } else {
         int var4 = this.fileNameHashTables[var3].get_base(class150.hashString_base(var2));
         return var4 >= 0;
      }
   }

   @ObfuscatedName("cu")
   @ObfuscatedSignature(
      descriptor = "(Ljava/lang/String;Ljava/lang/String;I)[B",
      garbageValue = "1936244729"
   )
   public byte[] takeFileByNames_base(String var1, String var2) {
      var1 = var1.toLowerCase();
      var2 = var2.toLowerCase();
      int var3 = this.groupNameHashTable.get_base(class150.hashString_base(var1));
      int var4 = this.fileNameHashTables[var3].get_base(class150.hashString_base(var2));
      return this.takeFile_base(var3, var4);
   }

   @ObfuscatedName("ch")
   @ObfuscatedSignature(
      descriptor = "(Ljava/lang/String;Ljava/lang/String;B)Z",
      garbageValue = "100"
   )
   public boolean tryLoadFileByNames_base(String var1, String var2) {
      var1 = var1.toLowerCase();
      var2 = var2.toLowerCase();
      int var3 = this.groupNameHashTable.get_base(class150.hashString_base(var1));
      int var4 = this.fileNameHashTables[var3].get_base(class150.hashString_base(var2));
      return this.tryLoadFile_base(var3, var4);
   }

   @ObfuscatedName("cb")
   @ObfuscatedSignature(
      descriptor = "(Ljava/lang/String;I)Z",
      garbageValue = "-1281128467"
   )
   public boolean tryLoadGroupByName_base(String var1) {
      var1 = var1.toLowerCase();
      int var2 = this.groupNameHashTable.get_base(class150.hashString_base(var1));
      return this.tryLoadGroup_base(var2);
   }

   @ObfuscatedName("cz")
   @ObfuscatedSignature(
      descriptor = "(Ljava/lang/String;I)V",
      garbageValue = "-1287445108"
   )
   public void loadRegionFromName_base(String var1) {
      var1 = var1.toLowerCase();
      int var2 = this.groupNameHashTable.get_base(class150.hashString_base(var1));
      if(var2 >= 0) {
         this.loadRegionFromGroup_base(var2);
      }
   }

   @ObfuscatedName("cy")
   @ObfuscatedSignature(
      descriptor = "(Ljava/lang/String;I)I",
      garbageValue = "-1550662505"
   )
   public int groupLoadPercentByName_base(String var1) {
      var1 = var1.toLowerCase();
      int var2 = this.groupNameHashTable.get_base(class150.hashString_base(var1));
      return this.groupLoadPercent_base(var2);
   }

   @ObfuscatedSignature(
      descriptor = "(III)[B",
      garbageValue = "946380186"
   )
   public byte[] copy$takeFile(int var1, int var2, int var3) {
      return this.takeFileEncrypted_base(var1, var2, (int[])null);
   }

   public boolean isOverlayOutdated() {
      return this.overlayOutdated;
   }

   public int getGroupCount() {
      return this.groupCount;
   }

   public int[] getFileCounts() {
      return this.fileCounts;
   }

   public int[][] getFileIds() {
      return this.fileIds;
   }

   public byte[] getConfigData(int var1, int var2) {
      return this.takeFile_base(var1, var2);
   }

   public byte[] loadData(int var1, int var2) {
      return this.getFile_base(var1, var2);
   }

   public int[] getFileIds(int var1) {
      return this.getGroupFileIds_base(var1);
   }

   public int getGroupFileCount(int var1) {
      return this.getGroupFileCount_base(var1);
   }
}
