
/*

SPDX-FileCopyrightText: Copyright 2021 Siemens
SPDX-License: GPL-3.0-only
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 3.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.


 */


package javareporter;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

import org.jd.core.v1.api.loader.Loader;
import org.jd.core.v1.api.loader.LoaderException;

public class JarAndClassLoader implements Loader {
	
	
    protected HashMap<String, byte[]> map = new HashMap<>();
    
    
    private void AddByteArrayToMap(InputStream inputStream, String name) throws IOException
    {
    	byte[] buffer = new byte[1024];
    	ByteArrayOutputStream out = new ByteArrayOutputStream();
        int read = inputStream.read(buffer);

        while (read > 0) {
            out.write(buffer, 0, read);
            read = inputStream.read(buffer);
        }

        map.put(name, out.toByteArray());
    }
    
    // if isJar = true, we have a jar file, otherwise, we have a class file
    public JarAndClassLoader(File inputFile, boolean isJar) throws LoaderException, FileNotFoundException {
    	
		InputStream inputStream = new FileInputStream(inputFile);
		//reset the version read in from the last jar before processing the next file
		Utils.ClearNXVersion();
		
    	if (isJar)
        {
    		//Read the jar files and add the class files from it to the map
    		//can also get the NXSigningResource.res file to get the nx version number
	        try (ZipInputStream zis = new ZipInputStream(inputStream)) 
	        {
	            ZipEntry ze = zis.getNextEntry();
	
	            while (ze != null) {
	                if (ze.isDirectory() == false) {
	                	
	                	
	                	if (ze.getName().contains("NXSigningResource.res"))
	                	{
	                		try {
								Utils.ReadNXOpenSigningResource(zis);
							} catch (Exception e) {
								e.printStackTrace();
							}
	                	}
	                	else
	                	{
	                		AddByteArrayToMap(zis, ze.getName());
		                	
	                	}
	                }
	                ze = zis.getNextEntry();
	            }
	            zis.closeEntry();
	        } 
	        catch (IOException e) 
	        {
	            throw new LoaderException(e);
	        }
        }
    	else
    	{
            try (ByteArrayOutputStream out=new ByteArrayOutputStream()) 
            {
            	AddByteArrayToMap(inputStream, inputFile.getName());
            } catch (Exception e) {
                throw new LoaderException(e);
            }
    	}
    }

    public HashMap<String, byte[]> getMap() { return map; }

    @Override
    public byte[] load(String internalName) throws LoaderException {
        return map.get(internalName);
    }

    @Override
    public boolean canLoad(String internalName) {
        return map.containsKey(internalName);
    }
}
