 
 import Foundation
 
-extension Flock {
-    static let Zewo = SystemdTasks(provider: ZewoProvider()).createTasks()
+public protocol SystemdProvider {
+    var name: String { get }
 }
 
-class ZewoProvider: SystemdProvider {
- 
-    let name = "Zewo"
+extension SystemdProvider {
     
+    var namespace: String {
+        return name.lowercased()
+    }
+    
+    var serviceFile: String {
+        return "/lib/systemd/system/\(namespace).service"
+    }
 }
 
-class SystemdTasks {
+public class SystemdTasks {
     
     let provider: SystemdProvider
     
-    init(provider: SystemdProvider) {
+    public init(provider: SystemdProvider) {
         self.provider = provider
     }
     
-    func createTasks() -> [Task] {
+    public func createTasks() -> [Task] {
         return [
+            WriteServiceTask(provider: provider),
             StartTask(provider: provider),
             StopTask(provider: provider),
             RestartTask(provider: provider)
         ]
+    }
+    
+}
+
+class WriteServiceTask: Task {
+    
+    let name = "write-service"
+    let namespace: String
+    let provider: SystemdProvider
+    
+    init(provider: SystemdProvider) {
+        self.namespace = provider.namespace
+        self.provider = provider
+    }
+    
+    func run(on server: Server) throws {
+        let path = provider.serviceFile
+        
+        guard !server.fileExists(path) else {
+            return
+        }
+        
+        print("Writing \(path)")
+        try server.execute("echo \"\(generateServiceContents())\" > \(path)")
+    }
+    
+    func generateServiceContents() -> String {
+        return [
+            "[Unit]",
+            "Description=\"Starts the \(provider.name) server\"",
+            "",
+            "[Service]",
+            "ExecStart=\"\(Paths.executable)\"",
+            "Restart=on-failure",
+            ""
+            ].joined(separator: "\n")
     }
     
 }

    }
    
    func run(on server: Server) throws {
        let path = "/lib/systemd/system/\(provider.namespace).service"
        print("Writing \(path)")
        
        try server.execute("echo \"\(generateServiceContents())\" > \(path)")
        
        print("Starting \(provider.name)")
        
        try server.execute("service start \(provider.namespace)")
    }
    
    func generateServiceContents() -> String {
        return [
            "[Unit]",
            "Description=\"Starts the \(provider.name) server\"",
            "",
            "[Service]",
            "ExecStart=\"\(Paths.executable)\"",
            "Restart=on-failure",
            ""
        ].joined(separator: "\n")
    }
    
}

    
    func run(on server: Server) throws {
        print("Stopping \(provider.name)")
        try server.execute("service \(provider.namespace) stop")
    }
    
}
