/*
 * Decompiled with CFR 0.152.
 */
package com.hst.framework.util;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InvalidClassException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectStreamClass;
import java.io.OutputStream;
import java.util.LinkedList;

public class HstCloneUtil {
    public static Object deepClone(Object object) {
        try {
            return HstCloneUtil.cloneX(object);
        }
        catch (IOException e) {
            throw new IllegalArgumentException(e.getMessage());
        }
        catch (ClassNotFoundException e) {
            throw new IllegalArgumentException(e.getMessage());
        }
    }

    private static Object cloneX(Object x) throws IOException, ClassNotFoundException {
        ByteArrayOutputStream bout = new ByteArrayOutputStream();
        CloneOutput cout = new CloneOutput(bout);
        cout.writeObject(x);
        byte[] bytes = bout.toByteArray();
        ByteArrayInputStream bin = new ByteArrayInputStream(bytes);
        CloneInput cin = new CloneInput(bin, cout);
        Object clone = cin.readObject();
        return clone;
    }

    private static class CloneInput
    extends ObjectInputStream {
        private final CloneOutput output;

        CloneInput(InputStream in, CloneOutput output) throws IOException {
            super(in);
            this.output = output;
        }

        protected Class resolveClass(ObjectStreamClass osc) throws IOException, ClassNotFoundException {
            String found;
            Class c = (Class)this.output.classQueue.getFirst();
            this.output.classQueue.removeFirst();
            String expected = osc.getName();
            String string = found = c == null ? null : c.getName();
            if (!expected.equals(found)) {
                throw new InvalidClassException("Classes desynchronized: found " + found + " when expecting " + expected);
            }
            return c;
        }

        protected Class resolveProxyClass(String[] interfaceNames) throws IOException, ClassNotFoundException {
            Class c = (Class)this.output.classQueue.getFirst();
            this.output.classQueue.removeFirst();
            return c;
        }
    }

    private static class CloneOutput
    extends ObjectOutputStream {
        LinkedList classQueue = new LinkedList();

        CloneOutput(OutputStream out) throws IOException {
            super(out);
        }

        protected void annotateClass(Class c) {
            this.classQueue.add(c);
        }

        protected void annotateProxyClass(Class c) {
            this.classQueue.add(c);
        }
    }
}
