package com.hackaton.lviv.monitoring;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import com.hackaton.lviv.entity.Alert;
import com.hackaton.lviv.entity.Rule;
import com.hackaton.lviv.repository.RuleRepository;
import com.hackaton.lviv.service.AggregatorService;
import com.hackaton.lviv.service.AlertService;
import com.hackaton.lviv.service.RulesService;
import com.hackaton.lviv.utils.Scp;

@Component
public class LogMonitoringJob {
	
    public static final String PATH_TO_LOGS = "/home/developer/logsArchive";
    
	public static final String LINE_WITH_RULE_REGEX = "^(\\d+)/(\\d+)/(\\d+) (\\d+):(\\d+):(\\d+) \\[(\\w+)\\](.*)";
	
	public static final int ERROR_LEVEL_GROUP_NUMBER = 7;

	public static int logNumber = 1;
	
	@Autowired
	RuleRepository ruleRepository;
	
	@Autowired
	private AggregatorService aggregatorService;
	
	@Autowired
	RulesService rulesService;
	
	@Autowired
	AlertService alertService;

	@Scheduled(cron = "0/10 * * * * *")
	public void checkLogs() throws IOException {
	    // retrieving login info and downloading logs for each server using API  
		Scp ssh = new Scp();
	    final long timestamp = System.currentTimeMillis();
	    String host = "104.131.68.169";
        int port = 22;
        String username = "root";
        String password = "1234567890";
        String fileFrom = "/root/var/www/logs/error" + logNumber +".log";
        
        // create folder for storing logs if one does not exist
        // replace tempHost for real host name
        String tempHost = "/logger01.prod2.cloud.cheggnet.com".replace(".", "_");
        String logServerUrl = PATH_TO_LOGS + tempHost;
        if (new File(logServerUrl).mkdirs() == true) {
            System.out.println("Folder '" + logServerUrl + "' for storing server logs created");
        }
        
        String fileTo = logServerUrl + "/error" + logNumber + "_" + timestamp + ".log";
        System.out.println(new Date(timestamp) + " - cron launched");
        ssh.scpFileFromServer(host, port, username, password, fileFrom, fileTo);
        // when we copy one log file, go to the next file 
        logNumber++;
        if (logNumber > 6) {
            logNumber = 1;
        }
        
        List<Rule> rules = ruleRepository.findAll();
        Rule tempRule = null;
        // reading copied file line by line and analyzing it
        // retrieving list of available rules, we assume that we have 
        // ERROR, WARN and INFO rules
        List<String> errorList = new ArrayList<String>();
        List<String> warnList = new ArrayList<String>();
        List<String> infoList = new ArrayList<String>();
        BufferedReader br = new BufferedReader(new FileReader(fileTo));
        String line;
        while ((line = br.readLine()) != null) {
        	
        	//for(Rule rule: rules) {
        		Pattern pattern = Pattern.compile(rules.get(0).getRegex());
        	
        	Matcher matcher = pattern.matcher(line);
        	if (matcher.matches()) {
        		String logLevel = matcher.group(ERROR_LEVEL_GROUP_NUMBER);
        		if (logLevel.equalsIgnoreCase(rules.get(0).getText())) {
        			errorList.add(line);
        			tempRule = rules.get(0);
        		} else if (logLevel.equalsIgnoreCase(rules.get(0).getText())) {
        			warnList.add(line);
        			tempRule = rules.get(0);
        		} else if (logLevel.equalsIgnoreCase(rules.get(0).getText())) {
        			infoList.add(line);
        			tempRule = rules.get(0);
        		}
        	}
        }
        br.close();
		System.out.println("Found: errors=" + errorList.size() + ", warns="
				+ warnList.size() + ", info=" + infoList.size() + " in file " + fileTo);
		// saving errorList, warnList, infoList to database using API
		
		// saving errorList
		storeResultToDB(tempRule.getRegex(), tempRule.getText(), errorList, tempRule);
//		storeResultToDB(LINE_WITH_RULE_REGEX, "warn", warnList);
//		storeResultToDB(LINE_WITH_RULE_REGEX, "info", infoList);
        
	}

	private List<Alert> storeResultToDB(String pattern, String text, List<String> alerts, Rule rule ) {
		
//		Rule storedRule = rulesService.constructRule(pattern, text);
//		storedRule = rulesService.saveRuleToDatabase(storedRule);
/*		List<Rule> ruleList = rulesService.find(storedRule);
		
		if(ruleList.isEmpty()) {
			storedRule = rulesService.saveRuleToDatabase(storedRule);
		} else {
			storedRule = ruleList.get(0);
		}*/
		
//		Rule storedRule = rulesService.saveRuleToDatabase( rulesService.constructRule(pattern, text) );
		List<Alert> storedAlerts = alertService.saveAlertsToDatabase( alertService.constructAlerts(alerts ,rule) );
		
		return storedAlerts;
	}
	
}
