package com.sumologic.jenkins.jenkinssumologicplugin.listeners;

import com.sumologic.jenkins.jenkinssumologicplugin.PluginDescriptorImpl;
import com.sumologic.jenkins.jenkinssumologicplugin.constants.AuditEventTypeEnum;
import hudson.Extension;
import hudson.XmlFile;
import hudson.model.Item;
import hudson.model.Saveable;
import hudson.model.User;
import hudson.model.listeners.SaveableListener;
import jenkins.model.Jenkins;
import org.apache.commons.codec.digest.DigestUtils;

import java.io.*;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.util.Base64;
import java.util.WeakHashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Pattern;

import static com.sumologic.jenkins.jenkinssumologicplugin.constants.SumoConstants.IGNORE_PATTERN;
import static com.sumologic.jenkins.jenkinssumologicplugin.utility.CommonModelFactory.*;

/**
 * Sumo Logic plugin for Jenkins model.
 * <p>
 * For any config related change
 * <p>
 * Created by Sourabh Jain on 5/2019.
 */
@Extension
public class SumoJobConfigListener extends SaveableListener {

    private static final Logger LOG = Logger.getLogger(SumoJobConfigListener.class.getName());

    private static final Pattern IGNORED = Pattern.compile(IGNORE_PATTERN, Pattern.CASE_INSENSITIVE);
    private final WeakHashMap<String, Integer> cached = new WeakHashMap<>(512);

    @Override
    public void onChange(Saveable saveable, XmlFile file) {
        try {
            PluginDescriptorImpl pluginDescriptor = PluginDescriptorImpl.getInstance();
            if (!pluginDescriptor.isAuditLogEnabled()){
                return;
            }
            String configPath = file.getFile().getAbsolutePath();
            if (saveable == null || IGNORED.matcher(configPath).find()
                    || "SYSTEM".equals(Jenkins.getAuthentication().getName())
                    || saveable instanceof User) {
                return;
            }

            String configContent = file.asString();
            String checkSum = DigestUtils.md5Hex(configPath + configContent);
            if (cached.containsKey(checkSum)) {
                return;
            }
            cached.put(checkSum, 0);
            System.out.println("asaskfv");
            String encodeFileToString = Base64.getEncoder().encodeToString(file.asString().getBytes());

            String oldFileAsString = null;

            if (pluginDescriptor.isKeepOldConfigData()) {
                File oldFile = getOldFile(file);
                byte[] bytes = fileToString(oldFile);
                oldFileAsString = Base64.getEncoder().encodeToString(bytes);

                try {
                    Files.copy(file.getFile().toPath(), oldFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
                } catch (IOException e) {
                    LOG.log(Level.WARNING, "An error occurred while copying the new configuration ", e);
                }
            }


            if (!encodeFileToString.equals(oldFileAsString)) {
                captureConfigChanges(encodeFileToString, oldFileAsString, AuditEventTypeEnum.CHANGES_IN_CONFIG, getRelativeJenkinsHomePath(file.getFile().getAbsolutePath()));
            }
            if (!(saveable instanceof Item)) {
                captureItemAuditEvent(AuditEventTypeEnum.UPDATED, file.getFile().getName(), null);
            }
        } catch (Exception exception) {
            LOG.log(Level.WARNING, "An error occurred while Checking the Job Configuration", exception);
        }
    }

    private static File getOldFile(XmlFile file) {
        File oldFile = null;
        String oldFileName = file.getFile().getName().replace(".xml", "") + "_old.xml";
        String pathForOldFile = file.getFile().getParent() + File.separator + oldFileName;
        if (file.getFile().getParentFile() != null) {
            File parentFile = file.getFile().getParentFile();
            if (parentFile.listFiles() != null) {
                File[] files = parentFile.listFiles();
                if (files != null) {
                    for (File fileNames : files) {
                        if (fileNames != null) {
                            if (fileNames.getName().matches(oldFileName)) {
                                oldFile = fileNames;
                                break;
                            }
                        }
                    }
                }
            }
        }

        if (oldFile == null) {
            oldFile = new File(pathForOldFile);
        }
        return oldFile;
    }

    private static byte[] fileToString(File file) throws IOException {
        BufferedInputStream reader = null;
        try {
            if (file.length() > 0) {
                int length = (int) file.length();
                reader = new BufferedInputStream(new FileInputStream(file));
                byte[] bytes = new byte[length];
                reader.read(bytes, 0, length);
                reader.close();
                return bytes;
            }
        } catch (RuntimeException e) {
            throw e;
        } catch (Exception ex) {
            LOG.log(Level.WARNING, "Conversion to string failed for "+file.toPath(), ex);
        } finally {
            if (reader != null) {
                reader.close();
            }
        }
        return new byte[0];
    }
}

@@ -2222,51 +2222,8 @@
 0);%0A
-            System.out.println(%22asaskfv%22);%0A
     

removing print statement