/*
 * Copyright 2019 EPAM Systems
 *
 * 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 com.epam.ta.reportportal.entity.enums;

import java.util.Arrays;
import java.util.Comparator;
import java.util.Optional;

public enum TestItemTypeEnum implements Comparable<TestItemTypeEnum> {

	//@formatter:off
SUITE(Constants.SUITE_LEVEL, true),
STORY(Constants.SUITE_LEVEL, true),
TEST(Constants.TEST_LEVEL, true),
SCENARIO(Constants.TEST_LEVEL, true),
STEP(Constants.STEP_LEVEL, true),
BEFORE_CLASS(Constants.STEP_LEVEL, false),
BEFORE_GROUPS(Constants.STEP_LEVEL, false),
BEFORE_METHOD(Constants.STEP_LEVEL, false),
BEFORE_SUITE(Constants.TEST_LEVEL, false),
BEFORE_TEST(Constants.STEP_LEVEL, false),
AFTER_CLASS(Constants.STEP_LEVEL, false),
AFTER_GROUPS(Constants.STEP_LEVEL, false),
AFTER_METHOD(Constants.STEP_LEVEL, false),
AFTER_SUITE(Constants.TEST_LEVEL, false),
AFTER_TEST(Constants.STEP_LEVEL, false);
//@formatter:on

	private int level;
	private boolean awareStatistics;

	TestItemTypeEnum(int level, boolean awareStatistics) {
		this.level = level;
		this.awareStatistics = awareStatistics;
	}

	public static Optional<TestItemTypeEnum> fromValue(String value) {
		return Arrays.stream(TestItemTypeEnum.values()).filter(type -> type.name().equalsIgnoreCase(value)).findAny();
	}

	public boolean sameLevel(TestItemTypeEnum other) {
		return 0 == LEVEL_COMPARATOR.compare(this, other);
	}

	/**
	 * Is level of current item higher than level of specified
	 *
	 * @param type Item to compare
	 * @return
	 */
	public boolean higherThan(TestItemTypeEnum type) {
		return LEVEL_COMPARATOR.compare(this, type) > 0;
	}

	/**
	 * Is level of current item lower than level of specified
	 *
	 * @param type Item to compare
	 * @return
	 */
	public boolean lowerThan(TestItemTypeEnum type) {
		return LEVEL_COMPARATOR.compare(this, type) < 0;
	}

	public boolean awareStatistics() {
		return awareStatistics;
	}

	/**
	 * Level Comparator for TestItem types. Returns TRUE of level of first
	 * object is <b>lower</b> than level of second object
	 *
	 * @author Andrei Varabyeu
	 */
	private static final Comparator<TestItemTypeEnum> LEVEL_COMPARATOR = (TestItemTypeEnum o1, TestItemTypeEnum o2) -> (o1.level
			== o2.level) ? 0 : (o1.level < o2.level) ? 1 : -1;

	public static class Constants {
		public static final int SUITE_LEVEL = 0;
		public static final int TEST_LEVEL = 1;
		public static final int STEP_LEVEL = 2;
	}
}

@@ -793,25 +793,8 @@
 %7B%0A%0A%09
-//@formatter:off%0A
 SUIT
@@ -825,16 +825,17 @@
  true),%0A
+%09
 STORY(Co
@@ -862,16 +862,17 @@
  true),%0A
+%09
 TEST(Con
@@ -897,16 +897,17 @@
  true),%0A
+%09
 SCENARIO
@@ -936,16 +936,17 @@
  true),%0A
+%09
 STEP(Con
@@ -967,24 +967,25 @@
 VEL, true),%0A
+%09
 BEFORE_CLASS
@@ -1011,24 +1011,25 @@
 EL, false),%0A
+%09
 BEFORE_GROUP
@@ -1056,24 +1056,25 @@
 EL, false),%0A
+%09
 BEFORE_METHO
@@ -1101,24 +1101,25 @@
 EL, false),%0A
+%09
 BEFORE_SUITE
@@ -1149,16 +1149,17 @@
 false),%0A
+%09
 BEFORE_T
@@ -1188,24 +1188,25 @@
 EL, false),%0A
+%09
 AFTER_CLASS(
@@ -1231,24 +1231,25 @@
 EL, false),%0A
+%09
 AFTER_GROUPS
@@ -1275,24 +1275,25 @@
 EL, false),%0A
+%09
 AFTER_METHOD
@@ -1319,24 +1319,25 @@
 EL, false),%0A
+%09
 AFTER_SUITE(
@@ -1366,16 +1366,17 @@
 false),%0A
+%09
 AFTER_TE
@@ -1411,24 +1411,8 @@
 se);
-%0A//@formatter:on
 %0A%0A%09p
@@ -2392,24 +2392,69 @@
 istics;%0A%09%7D%0A%0A
+%09public int getLevel() %7B%0A%09%09return level;%0A%09%7D%0A%0A
 %09/**%0A%09 * Lev
@@ -2685,115 +2685,54 @@
  = (
-TestItemTypeEnum o1, TestItemTypeEnum o2) -%3E (o1.level%0A%09%09%09== o2.level) ? 0 : (o1
+o1, o2) -%3E Integer.compare(o2
 .level
- %3C o2
+, o1
 .level)
- ? 1 : -1
 ;%0A%0A%09

add level getter