/*
 * Copyright (c) 1998, 2019 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, Long.valueOf(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)).longValue();

                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) {
        }
    }
}
