package ru.yandex.wmconsole.service;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.StringTokenizer;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Required;

import ru.yandex.wmconsole.data.ToolEnum;
import ru.yandex.wmconsole.data.info.LogInfo;
import ru.yandex.wmtools.common.error.InternalException;
import ru.yandex.wmtools.common.error.InternalProblem;
import ru.yandex.wmtools.common.service.IService;
import ru.yandex.wmtools.common.service.UserService;

/**
 * @author ailyin
 */
public class LogViewerService implements IService {

    private static final int EXAMPLES_COUNT = 30;

    private UserService userService;
    private File logsFolder;
    private Logger log = LoggerFactory.getLogger(LogViewerService.class);

    public List<LogInfo> getLogInfo(URL userUrl, ToolEnum tool) throws InternalException {
        File toolLogPath = new File(logsFolder, tool.toString().toLowerCase() + ".total");
        BufferedReader reader = null;
        String urlStr = userUrl.toString().toLowerCase();
        try {
            reader = new BufferedReader(new FileReader(toolLogPath));

            List<LogInfo> result = new ArrayList<LogInfo>();

            String line = reader.readLine();
            while (line != null) {
                StringTokenizer tokenizer = new StringTokenizer(line);
                String url = tokenizer.nextToken();
                if (url.toLowerCase().contains(urlStr)) {
                    String dateString = tokenizer.nextToken();
                    Date date = dateString != null ? new Date(Long.parseLong(dateString)) : null;

                    if (ToolEnum.ADDURL.equals(tool) || ToolEnum.DELURL.equals(tool)) {
                        tokenizer.nextToken(); // skip ip
                    }

                    Long uid;
                    try {
                        String uidString = tokenizer.nextToken();
                        uid = uidString != null ? Long.parseLong(uidString) : null;
                    } catch (NumberFormatException e) {
                        uid = null;
                    }

                    result.add(new LogInfo(url, date, (uid == null) ? null : userService.getUserInfo(uid)));
                }

                line = reader.readLine();
            }

            return result;
        } catch (FileNotFoundException e) {
            log.error("File " + toolLogPath.getAbsolutePath() + " not found", e);
            return Collections.emptyList();
        } catch (IOException e) {
            log.error("IO Exception", e);
            throw new InternalException(InternalProblem.READ_FILE_ERROR,
                    "Failed to read from file " + toolLogPath.getAbsolutePath(), e);
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    // ignore
                }
            }
        }
    }

    public List<LogInfo> getLogExample(ToolEnum tool) throws InternalException {
        File toolLogPath = new File(logsFolder, tool.toString().toLowerCase() + ".examples");

        BufferedReader reader = null;
        try {
            reader = new BufferedReader(new FileReader(toolLogPath));

            List<LogInfo> result = new ArrayList<LogInfo>();

            String line = reader.readLine();
            int count = 0;
            while (line != null) {
                StringTokenizer tokenizer = new StringTokenizer(line);
                String url = tokenizer.nextToken();
                String dateString = tokenizer.nextToken();
                Date date = dateString != null ? new Date(Long.parseLong(dateString)) : null;

                if (ToolEnum.ADDURL.equals(tool) || ToolEnum.DELURL.equals(tool)) {
                    tokenizer.nextToken(); // skip ip
                }

                Long uid;
                try {
                    String uidString = tokenizer.nextToken();
                    uid = uidString != null ? Long.parseLong(uidString) : null;
                } catch (NumberFormatException e) {
                    uid = null;
                }

                result.add(new LogInfo(url, date, (uid == null) ? null : userService.getUserInfo(uid)));
                count++;

                if (count >= EXAMPLES_COUNT) {
                   break;
                }

                line = reader.readLine();
            }

            return result;
        } catch (FileNotFoundException e) {
            return Collections.emptyList();
        } catch (IOException e) {
            throw new InternalException(InternalProblem.READ_FILE_ERROR,
                    "Failed to read from file " + toolLogPath.getAbsolutePath(), e);
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    // ignore
                }
            }
        }
    }

    @Required
    public void setUserService(UserService userService) {
        this.userService = userService;
    }

    @Required
    public void setLogsFolder(File logsFolder) {
        this.logsFolder = logsFolder;
    }
}
