/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.dlab;

import com.epam.dlab.configuration.BillingToolConfiguration;
import com.epam.dlab.configuration.BillingToolConfigurationFactory;
import com.epam.dlab.configuration.SchedulerConfiguration;
import com.epam.dlab.core.parser.ParserBase;
import com.epam.dlab.exceptions.AdapterException;
import com.epam.dlab.exceptions.DlabException;
import com.epam.dlab.exceptions.InitializationException;
import com.epam.dlab.exceptions.ParseException;
import com.epam.dlab.util.ServiceUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Arrays;

/**
 * Billing scheduler for loading billing report.
 */
public class BillingScheduler implements Runnable {
	private static final Logger LOGGER = LoggerFactory.getLogger(BillingScheduler.class);

	/**
	 * Timeout for check the schedule in milliseconds.
	 */
	private static final long CHECK_TIMEOUT_MILLIS = 60000;

	/**
	 * Billing scheduler instance.
	 */
	private static BillingScheduler scheduler;
	private final boolean enabled;
	private final BillingToolConfiguration configuration;

	/**
	 * Starts the scheduler for given configuration.
	 *
	 * @param filename the name of file for billing configuration.
	 * @throws InitializationException
	 */
	public static void start(String filename) throws InitializationException {
		if (scheduler == null) {
			scheduler = new BillingScheduler(filename);
			scheduler.thread.start();
		} else {
			LOGGER.debug("Billing scheduler already started");
		}
	}

	/**
	 * Stops the scheduler.
	 */
	public static void stop() {
		if (scheduler.thread != null) {
			LOGGER.debug("Billing scheduler will be stopped ...");
			synchronized (scheduler.thread) {
				scheduler.thread.interrupt();
				scheduler.thread = null;
			}
			LOGGER.info("Scheduler has been stopped");
		}
	}


	/**
	 * Thread of the scheduler.
	 */
	private Thread thread = new Thread(this, this.getClass().getSimpleName());

	/**
	 * Name of configuration file.
	 */
	private final String confFilename;

	/**
	 * Current schedule.
	 */
	private SchedulerConfiguration schedule;

	/**
	 * Instantiate billing scheduler for given configuration.
	 *
	 * @param filename the name of file for billing configuration.
	 * @throws InitializationException
	 */
	public BillingScheduler(String filename) throws InitializationException {
		this.confFilename = filename;
		LOGGER.debug("Billing report configuration file: {}", filename);
		configuration = BillingToolConfigurationFactory.build(confFilename, BillingToolConfiguration.class);
		this.enabled = configuration.isBillingEnabled();
		setSchedule(configuration);
	}

	/**
	 * Loads the billing report.
	 *
	 * @throws InitializationException
	 * @throws AdapterException
	 * @throws ParseException
	 */
	private void load() throws InitializationException, AdapterException, ParseException {
		ParserBase parser = configuration.build();
		long time = schedule.getNearTime().getTimeInMillis();
		if (setSchedule(configuration)) {
			if (time != schedule.getNearTime().getTimeInMillis()) {
				LOGGER.info("Previous billing schedule has been canceled");
				return;
			}
		}

		LOGGER.info("Try to laod billing report for configuration: {}", configuration);
		parser.parse();
		if (!parser.getStatistics().isEmpty()) {
			LOGGER.info("Billing report parser statistics:");
			for (int i = 0; i < parser.getStatistics().size(); i++) {
				LOGGER.info("  {}", parser.getStatistics().get(i).toString());
			}
		}
	}

	/**
	 * Read the schedule from configuration.
	 *
	 * @param configuration the billing configuration.
	 * @return <b>true>/b> if new schedule was loaded, otherwise <b>false</b>.
	 * @throws InitializationException
	 */
	private boolean setSchedule(BillingToolConfiguration configuration) throws InitializationException {
		SchedulerConfiguration schedulerConfiguration = configuration.getScheduler();
		boolean isModified = false;
		if (schedulerConfiguration == null) {
			throw new InitializationException(String.format("Schedule of billing report in configuration file \"%s " +
					"not found", confFilename));
		}
		if (this.schedule == null) {
			isModified = true;
			LOGGER.debug("Billing report schedule: {}", schedulerConfiguration);
		} else {
			this.schedule.adjustStartTime();
			if (!schedulerConfiguration.equals(this.schedule)) {
				isModified = true;
				LOGGER.debug("New billing report schedule has been loaded: {}", schedulerConfiguration);
			}
		}

		try {
			this.schedule = new SchedulerConfiguration();
			this.schedule.setSchedule(schedulerConfiguration.getSchedule());
			this.schedule.build();
		} catch (Exception e) {
			throw new InitializationException("Cannot configure billing scheduler. " + e.getLocalizedMessage(), e);
		}

		return isModified;
	}

	@Override
	public void run() {
		if (enabled) {
			LOGGER.info("Billing scheduler has been started");
			long startTimeMillis = schedule.getNextTime().getTimeInMillis();
			long timeMillis;
			LOGGER.info("Billing report will be loaded at {}", schedule.getNextTime().getTime());

			try {
				while (!Thread.currentThread().isInterrupted()) {
					if (startTimeMillis <= System.currentTimeMillis()) {
						try {
							LOGGER.debug("Try to load billing report for schedule {}",
									schedule.getNextTime().getTime());
							load();
						} catch (InitializationException | AdapterException | ParseException e) {
							LOGGER.error("Error loading billing report: {}", e.getLocalizedMessage(), e);
						}
						startTimeMillis = schedule.getNextTime().getTimeInMillis();
						LOGGER.info("Billing report will be loaded at {}", schedule.getNextTime().getTime());
					} else {
						schedule.adjustStartTime();
						timeMillis = schedule.getNextTime().getTimeInMillis();
						if (startTimeMillis != timeMillis) {
							LOGGER.info("Billing report will be loaded at {}", schedule.getNextTime().getTime());
							startTimeMillis = timeMillis;
						}
					}

					try {
						timeMillis = startTimeMillis - System.currentTimeMillis();
						if (timeMillis > 0) {
							timeMillis = Math.min(CHECK_TIMEOUT_MILLIS, timeMillis);
							Thread.sleep(timeMillis);
						}
					} catch (InterruptedException e) {
						LOGGER.warn("Billing scheduler interrupted", e);
						Thread.currentThread().interrupt();
					}
				}
			} catch (Exception e) {
				LOGGER.error("Unhandled billing report error: {}", e.getLocalizedMessage(), e);
			}
			LOGGER.info("Scheduler has been stopped");
		} else {
			LOGGER.info("Billing scheduler is disabled");
		}
	}


	/**
	 * Runs billing scheduler for given configuration file.
	 *
	 * @param args the arguments of command line.
	 * @throws InitializationException
	 */
	public static void main(String[] args) throws InitializationException {
		if (ServiceUtils.printAppVersion(BillingTool.class, args)) {
			return;
		}

		String confName = null;
		for (int i = 0; i < args.length; i++) {
			if (BillingTool.isKey("help", args[i])) {
				i++;
				Help.usage(i < args.length ? Arrays.copyOfRange(args, i, args.length) : null);
				return;
			} else if (BillingTool.isKey("conf", args[i])) {
				i++;
				if (i < args.length) {
					confName = args[i];
				} else {
					throw new InitializationException("Missing the name of configuration file");
				}
			} else {
				throw new InitializationException("Unknow argument: " + args[i]);
			}
		}

		if (confName == null) {
			Help.usage();
			throw new InitializationException("Missing arguments");
		}

		BillingTool.setLoggerLevel();
		try {
			start(confName);
		} catch (Exception e) {
			throw new DlabException("Billing scheduler failed", e);
		}
	}
}
