/*
 * Copyright 2012 Erwin Müller <erwin.mueller@deventm.org>
 *
 * This file is part of sscontrol-hostname.
 *
 * sscontrol-hostname is free software: you can redistribute it and/or modify it
 * under the terms of the GNU Affero General Public License as published by the
 * Free Software Foundation, either version 3 of the License, or (at your
 * option) any later version.
 *
 * sscontrol-hostname is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License
 * for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with sscontrol-hostname. If not, see <http://www.gnu.org/licenses/>.
 */
package com.anrisoftware.sscontrol.hostname.service;

import static com.anrisoftware.sscontrol.hostname.service.HostnameFactory.NAME;
import groovy.lang.Closure;
import groovy.lang.GroovyObjectSupport;
import groovy.lang.Script;

import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import javax.inject.Inject;
import javax.inject.Named;

import org.apache.commons.lang3.builder.ToStringBuilder;

import com.anrisoftware.resources.templates.api.TemplatesFactory;
import com.anrisoftware.sscontrol.core.api.ProfileService;
import com.anrisoftware.sscontrol.core.api.Service;
import com.anrisoftware.sscontrol.core.api.ServiceException;
import com.anrisoftware.sscontrol.workers.command.script.ScriptCommandWorkerFactory;
import com.anrisoftware.sscontrol.workers.text.tokentemplate.TokensTemplateWorkerFactory;
import com.google.inject.Provider;

class HostnameServiceImpl extends GroovyObjectSupport implements Service {

	/**
	 * @version 0.1
	 */
	private static final long serialVersionUID = 8026832603525631371L;

	private final HostnameServiceImplLogger log;

	private final Map<String, Provider<Script>> scripts;

	private ProfileService profile;

	private String hostname;

	private final TemplatesFactory templatesFactory;

	@Inject
	private TokensTemplateWorkerFactory tokensTemplateWorkerFactory;

	@Inject
	private ScriptCommandWorkerFactory scriptCommandWorkerFactory;

	@Inject
	HostnameServiceImpl(HostnameServiceImplLogger logger,
			Map<String, Provider<Script>> scripts, TemplatesFactory templates,
			@Named("hostname-service-properties") Properties properties) {
		this.log = logger;
		this.scripts = scripts;
		this.templatesFactory = templates;
	}

	public Object hostname(Closure<?> closure) {
		return this;
	}

	public Object set_hostname(String name) {
		log.checkHostname(this, name);
		hostname = name;
		log.hostnameSet(this, name);
		return this;
	}

	public String getHostname() {
		return hostname;
	}

	@Override
	public String getName() {
		return NAME;
	}

	public void setProfile(ProfileService newProfile) {
		profile = newProfile;
		log.profileSet(this, newProfile);
	}

	public ProfileService getProfile() {
		return profile;
	}

	@Override
	public Service call() throws ServiceException {
		String name = profile.getProfileName();
		Script script = scripts.get(name).get();
		Map<Class<?>, Object> workers = getWorkers();
		script.setProperty("workers", workers);
		script.setProperty("templatesFactory", templatesFactory);
		script.setProperty("system", profile.getEntry("system"));
		script.setProperty("profile", profile.getEntry(NAME));
		script.setProperty("service", this);
		script.setProperty("name", name);
		script.run();
		return this;
	}

	private Map<Class<?>, Object> getWorkers() {
		Map<Class<?>, Object> workers = new HashMap<Class<?>, Object>();
		workers.put(TokensTemplateWorkerFactory.class,
				tokensTemplateWorkerFactory);
		workers.put(ScriptCommandWorkerFactory.class,
				scriptCommandWorkerFactory);
		return workers;
	}

	@Override
	public String toString() {
		return new ToStringBuilder(this).toString();
	}

}

@@ -930,36 +930,8 @@
 ME;%0A
-import groovy.lang.Closure;%0A
 impo
@@ -2464,71 +2464,246 @@
 %7D%0A%0A%09
-public Object hostname(Closure%3C?%3E closure) %7B%0A%09%09return this;%0A%09%7D%0A
+/**%0A%09 * Entry point for the DNS service script.%0A%09 * %0A%09 * @return this %7B@link Service%7D.%0A%09 */%0A%09public Service hostname(Object closure) %7B%0A%09%09return this;%0A%09%7D%0A%0A%09/**%0A%09 * Sets the host name.%0A%09 * %0A%09 * @param name%0A%09 *            the host name.%0A%09 */
 %0A%09pu
@@ -2707,22 +2707,20 @@
 %09public 
-Object
+void
  set_hos
@@ -2824,33 +2824,87 @@
 name);%0A%09
-%09r
+%7D%0A%0A%09/**%0A%09 * R
 eturn
+s
  th
-is;%0A%09%7D%0A
+e host name.%0A%09 * %0A%09 * @return the host name.%0A%09 */
 %0A%09public
@@ -2946,24 +2946,73 @@
 stname;%0A%09%7D%0A%0A
+%09/**%0A%09 * Returns the hostname service name.%0A%09 */%0A
 %09@Override%0A%09
@@ -3052,24 +3052,146 @@
 n NAME;%0A%09%7D%0A%0A
+%09/**%0A%09 * Sets the profile for the DNS service.%0A%09 * %0A%09 * @param newProfile%0A%09 *            the %7B@link ProfileService%7D.%0A%09 */%0A
 %09public void
@@ -3295,16 +3295,116 @@
 e);%0A%09%7D%0A%0A
+%09/**%0A%09 * Returns the profile for the DNS service.%0A%09 * %0A%09 * @return the %7B@link ProfileService%7D.%0A%09 */%0A
 %09public 
@@ -4349,16 +4349,99 @@
 er(this)
+%0A%09%09%09%09.append(%22profile%22, profile.getProfileName())%0A%09%09%09%09.append(%22hostname%22, hostname)
 .toStrin

Add javadoc, returns the profile name in debug to-string