class CommonActions extends AbstractCaller {

    @Description("Use this action to stop SailFish till time you need.<br>" +
        "Specify time in the column TimeSync<br>" +
        "Time can be absolute (UTC) or relative.<br>" +
        "Examples:<br>" +
        "absolutely - 16:56:00<br>" +
        "relatively - 16:56:00+1m (where 1m = 1 minute)<br>" +
        "17:00:00+3h (where 3h = 3 hours)<br>" +
	    "17:13:00+25s (where 25s = 25 seconds)<br>")
    @CustomColumns(@CustomColumn(value = "TimeSync", required = true))
	@ActionMethod
	public void TimeSync(IActionContext actionContext, HashMap<?, ?> inputData) throws Exception
	{
        DateTimeFormatter df = DateTimeUtility.createFormatter("HH:mm:ss");

        int s_ms = 1000;
        int m_ms = 60000;
        int h_ms = 3600000;

        String value = ((String)unwrapFilters(inputData.get("TimeSync"))).trim();
        StringTokenizer t = new StringTokenizer(value, "+");

        List<String> tokens = new ArrayList<>();
		while (t.hasMoreTokens()) {
			tokens.add(t.nextToken().trim());
		}

        LocalDateTime p = null;
		try {
            p = DateTimeUtility.toLocalDateTime(LocalTime.parse(tokens.get(0), df));
        } catch (DateTimeParseException pe) {
			throw pe;
		}

        LocalDateTime currentLocalDateTime = DateTimeUtility.nowLocalDateTime();
        p = p.withYear(currentLocalDateTime.getYear());
        p = p.withMonth(currentLocalDateTime.getMonth().getValue());
        p = p.withDayOfMonth(currentLocalDateTime.getDayOfMonth());

        long abs = DateUtil.getMilliseconds(p);

		if (tokens.size() > 1) {
			for (int i = 1; i < tokens.size(); i++) {
				String token = tokens.get(i);
				int mul = Integer.parseInt(token.substring(0, token.length()-1));
				String smul2 = token.substring(token.length()-1, token.length());
				int mul2 = 0;
                if("h".equals(smul2)) {
                    mul2 = h_ms;
                } else if("m".equals(smul2)) {
                    mul2 = m_ms;
                } else if("s".equals(smul2)) {
                    mul2 = s_ms;
                }
				abs += mul*mul2;
			}
		}

		actionContext.getLogger().info("time sync till {}", p);
        if (System.currentTimeMillis() >= abs) {
            String errorDescription = p + " has already passed, now " + DateTimeUtility.nowLocalDateTime();
            throw new EPSCommonException(errorDescription);
        } else {
            Thread.sleep(abs - System.currentTimeMillis());
        }
    }

}