package com.github.aureliano.achmed.os.service;

import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.PathMatcher;
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.Arrays;

import org.apache.log4j.Logger;

import com.github.aureliano.achmed.command.CommandFacade;
import com.github.aureliano.achmed.command.CommandResponse;
import com.github.aureliano.achmed.exception.ServiceResourceException;
import com.github.aureliano.achmed.helper.StringHelper;

public class DebianService extends LinuxService {

	private static final Logger logger = Logger.getLogger(DebianService.class);
	private static final String SERVICE = "/usr/sbin/service";
	private static final String UPDATE_RC = "/usr/sbin/update-rc.d";
	private static final String INVOKE_RC = "/usr/sbin/invoke-rc.d";
	
	public DebianService() {
		super();
	}
	
	@Override
	public CommandResponse start() {
		if (this.isRunning()) {
			logger.debug("Service " + super.properties.getName() + " is already running.");
			return null;
		}
		
		if (StringHelper.isEmpty(super.properties.getBinary())) {
			return CommandFacade.executeCommand(SERVICE, super.properties.getName(), "start");
		}
		
		return super.start();
	}
	
	@Override
	public CommandResponse stop() {
		if (!this.isRunning()) {
			logger.debug("Service " + super.properties.getName() + " is not running.");
			return null;
		}
		
		if (StringHelper.isEmpty(super.properties.getBinary())) {
			return CommandFacade.executeCommand(SERVICE, super.properties.getName(), "stop");
		}
		
		return super.stop();
	}
	
	@Override
	public CommandResponse restart() {
		if ((super.properties.getHasRestart() != null) && (super.properties.getHasRestart())) {
			return CommandFacade.executeCommand(SERVICE, super.properties.getName(), "restart");
		}
		
		return super.restart();
	}
	
	@Override
	public boolean isRunning() {
		if ((super.properties.getHasStatus() != null) && (super.properties.getHasStatus())) {
			CommandResponse res = CommandFacade.executeCommand(SERVICE, super.properties.getName(), "status");
			return (res.getExitStatusCode() == 0);
		}
		
		return super.isRunning();
	}
	
	public boolean isEnabledInBootstrap() {
		CommandResponse res = CommandFacade.executeCommand(
			INVOKE_RC, "--quiet", "--query", super.properties.getName(), "start");
		
		if (Arrays.asList(104, 106).contains(res.getExitStatusCode())) {
			return true;
		} else if (Arrays.asList(101, 105).contains(res.getExitStatusCode())) {
			return (this.getStartLinkCount() >= 4);
		} else {
			return false;
		}
	}

	public CommandResponse enableBootstrap() {
		throw new UnsupportedOperationException("Not implemented yet.");
	}

	public CommandResponse disableBootstrap() {
		throw new UnsupportedOperationException("Not implemented yet.");
	}
	
	private int getStartLinkCount() {
		EtcFileVisitor matcherVisitor = new EtcFileVisitor();
		
		try {
			Files.walkFileTree(Paths.get("/etc"), matcherVisitor);
		} catch (IOException ex) {
			throw new ServiceResourceException(ex);
		}
		
		return matcherVisitor.getCounter();
	}
	
	private class EtcFileVisitor extends SimpleFileVisitor<Path> {
		
		private PathMatcher matcher;
		private int counter = 0;
		
		public EtcFileVisitor() {
			String pattern = "glob:/etc/rc*.d/S??" + "nginx";
			this.matcher = FileSystems.getDefault().getPathMatcher(pattern);
		}
		
		public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
			if (matcher.matches(file)) {
				System.out.println(file);
			}
			
			return FileVisitResult.CONTINUE;
		}
		
		public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
			return FileVisitResult.CONTINUE;
		}
		
		public int getCounter() {
			return counter;
		}
	}
}
@@ -2766,69 +2766,284 @@
 %7B%0A%09%09
-throw new UnsupportedOperationException(%22Not implemented yet.
+CommandResponse res = CommandFacade.executeCommand(UPDATE_RC, %22-f%22, super.properties.getName(), %22remove%22);%0A%09%09if (!res.isOK()) %7B%0A%09%09%09throw new ServiceResourceException(res.getError());%0A%09%09%7D%0A%09%09%0A%09%09return CommandFacade.executeCommand(UPDATE_RC, super.properties.getName(), %22defaults
 %22);%0A

Implement method to enable service in bootstrap.