/*
 * Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.tools.profiler;

import java.util.*;
import java.io.*;
import org.eclipse.persistence.internal.helper.*;
import org.eclipse.persistence.internal.localization.*;

/**
 * <p><b>Purpose</b>: Any information stored for a profile operation.
 *
 * @since TopLink 1.0
 * @author James Sutherland
 */
public class Profile implements Serializable, Cloneable {
    protected Class queryClass;
    protected Class domainClass;
    protected long numberOfInstancesEffected;
    protected Hashtable operationTimings;
    protected long localTime;
    protected long profileTime;
    protected long totalTime;
    protected long shortestTime;
    protected long longestTime;

    public Profile() {
        this.numberOfInstancesEffected = 0;
        this.operationTimings = new Hashtable();
        this.totalTime = 0;
        this.localTime = 0;
        this.longestTime = 0;
        this.shortestTime = -1;
        this.profileTime = 0;
    }

    public void addTiming(String name, long time) {
        getOperationTimings().put(name, time);
    }

    @Override
    public Object clone() {
        try {
            return super.clone();
        } catch (CloneNotSupportedException exception) {
            //Do nothing
        }

        return null;
    }

    public Class getDomainClass() {
        return domainClass;
    }

    public long getLocalTime() {
        return localTime;
    }

    public long getLongestTime() {
        return longestTime;
    }

    public long getNumberOfInstancesEffected() {
        return numberOfInstancesEffected;
    }

    public long getObjectsPerSecond() {
        if (getTotalTime() == 0) {
            return 0;
        }
        return (getNumberOfInstancesEffected() * 1000) / getTotalTime();
    }

    public Hashtable getOperationTimings() {
        return operationTimings;
    }

    public long getProfileTime() {
        return profileTime;
    }

    public Class getQueryClass() {
        return queryClass;
    }

    public long getShortestTime() {
        return shortestTime;
    }

    public long getTimePerObject() {
        if (getNumberOfInstancesEffected() == 0) {
            return 0;
        }
        return getTotalTime() / getNumberOfInstancesEffected();
    }

    public long getTotalTime() {
        return totalTime;
    }

    public void setDomainClass(Class domainClass) {
        this.domainClass = domainClass;
    }

    public void setLocalTime(long localTime) {
        this.localTime = localTime;
    }

    public void setLongestTime(long longestTime) {
        this.longestTime = longestTime;
    }

    public void setNumberOfInstancesEffected(long numberOfInstancesEffected) {
        this.numberOfInstancesEffected = numberOfInstancesEffected;
    }

    public void setOperationTimings(Hashtable operationTimings) {
        this.operationTimings = operationTimings;
    }

    public void setProfileTime(long profileTime) {
        this.profileTime = profileTime;
    }

    public void setQueryClass(Class queryClass) {
        this.queryClass = queryClass;
    }

    public void setShortestTime(long shortestTime) {
        this.shortestTime = shortestTime;
    }

    public void setTotalTime(long totalTime) {
        this.totalTime = totalTime;
    }

    @Override
    public String toString() {
        StringWriter writer = new StringWriter();

        write(writer, new PerformanceProfiler());

        return writer.toString();
    }

    public void write(Writer writer, PerformanceProfiler profiler) {
        String cr = Helper.cr();
        try {
            writer.write(ToStringLocalization.buildMessage("profile", null) + "(");
            if (getQueryClass() != null) {
                writer.write(Helper.getShortClassName(getQueryClass()) + "," + cr);
            } else {
                writer.write(cr);
            }
            if (getDomainClass() != null) {
                profiler.writeNestingTabs(writer);
                writer.write("\t" + ToStringLocalization.buildMessage("class", null) + "=" + getDomainClass().getName() + "," + cr);
            }
            if (getNumberOfInstancesEffected() != 0) {
                profiler.writeNestingTabs(writer);
                writer.write("\t" + ToStringLocalization.buildMessage("number_of_objects", null) + "=" + getNumberOfInstancesEffected() + "," + cr);
            }
            profiler.writeNestingTabs(writer);
            writer.write("\t" + ToStringLocalization.buildMessage("total_time", null) + "=" + getTotalTime() + "," + cr);
            profiler.writeNestingTabs(writer);
            writer.write("\t" + ToStringLocalization.buildMessage("local_time", null) + "=" + getLocalTime() + "," + cr);
            if (getProfileTime() != 0) {
                profiler.writeNestingTabs(writer);
                writer.write("\t" + ToStringLocalization.buildMessage("profiling_time", null) + "=" + getProfileTime() + "," + cr);
            }

            for (Enumeration operationNames = getOperationTimings().keys();
                     operationNames.hasMoreElements();) {
                String operationName = (String)operationNames.nextElement();
                long operationTime = (Long) getOperationTimings().get(operationName);

                if (operationTime != 0) {
                    profiler.writeNestingTabs(writer);
                    writer.write("\t" + operationName + "=" + operationTime + "," + cr);
                }
            }

            if (getTimePerObject() != 0) {
                profiler.writeNestingTabs(writer);
                writer.write("\t" + ToStringLocalization.buildMessage("time_object", null) + "=" + getTimePerObject() + "," + cr);
            }
            if (getObjectsPerSecond() != 0) {
                profiler.writeNestingTabs(writer);
                writer.write("\t" + ToStringLocalization.buildMessage("objects_second", null) + "=" + getObjectsPerSecond() + "," + cr);
            }
            if (getShortestTime() != -1) {
                profiler.writeNestingTabs(writer);
                writer.write("\t" + ToStringLocalization.buildMessage("shortestTime", null) + "=" + getShortestTime() + "," + cr);
            }
            if (getLongestTime() != 0) {
                profiler.writeNestingTabs(writer);
                writer.write("\t" + ToStringLocalization.buildMessage("longestTime", null) + "=" + getLongestTime() + "," + cr);
            }
            profiler.writeNestingTabs(writer);
            writer.write(")");

        } catch (IOException e) {
        }
    }
}
