/*
 * Copyright 2020 Martin Winandy
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
 * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations under the License.
 */

package org.tinylog.core.runtime;

import org.tinylog.core.internal.InternalLogger;

/**
 * Stack trace location implementation for legacy Java 8 that stores the location of a callee as numeric index.
 */
public class JavaIndexBasedStackTraceLocation extends AbstractJavaStackTraceLocation {

	private final int index;

	/**
	 * @param index The index of the callee in the stack trace
	 */
	JavaIndexBasedStackTraceLocation(int index) {
		this.index = index;
	}

	@Override
	public JavaIndexBasedStackTraceLocation push() {
		return new JavaIndexBasedStackTraceLocation(index + 1);
	}

	@Override
	public String getCallerClassName() {
		if (callerClassGetter != null) {
			try {
				Class<?> clazz = (Class<?>) callerClassGetter.invoke(index + 1);
				return clazz.getName();
			} catch (Throwable ex) {
				InternalLogger.error(ex, "Failed to extract class name at the stack trace depth of {}", index);
			}
		}

		StackTraceElement element = push().getCallerStackTraceElement();
		return element == null ? null : element.getClassName();
	}

	@Override
	public StackTraceElement getCallerStackTraceElement() {
		StackTraceElement[] trace = new Throwable().getStackTrace();
		if (index >= 0 && index < trace.length) {
			return trace[index];
		} else {
			InternalLogger.error(null, "There is no stack trace element at the depth of {}", index);
			return null;
		}
	}

}

@@ -1516,113 +1516,260 @@
 ment
- element = push().getCallerStackTraceElement();%0A%09%09return element == null ? null : element.getC
+%5B%5D trace = new Throwable().getStackTrace();%0A%09%09if (index %3E= 0 && index %3C trace.length) %7B%0A%09%09%09return trace%5Bindex%5D.getClassName();%0A%09%09%7D else %7B%0A%09%09%09InternalLogger.error(null, %22There is no c
 lass
-Name();
+ name at the stack trace depth of %7B%7D%22, index);%0A%09%09%09return null;%0A%09%09%7D
 %0A%09%7D%0A

Fix logged stack trace index in error message of Java stack trace loc