/*
 * Copyright 2017 Google, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License")
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.netflix.spinnaker.halyard.deploy.deployment.v1;

import com.netflix.spinnaker.halyard.config.config.v1.AtomicFileWriter;
import com.netflix.spinnaker.halyard.config.model.v1.node.DeploymentEnvironment.DeploymentType;
import com.netflix.spinnaker.halyard.config.problem.v1.ConfigProblemBuilder;
import com.netflix.spinnaker.halyard.core.error.v1.HalException;
import com.netflix.spinnaker.halyard.core.problem.v1.Problem.Severity;
import com.netflix.spinnaker.halyard.deploy.spinnaker.v1.SpinnakerEndpoints;
import com.netflix.spinnaker.halyard.deploy.spinnaker.v1.SpinnakerEndpoints.Service;
import com.netflix.spinnaker.halyard.deploy.spinnaker.v1.endpoint.EndpointType;

import java.io.IOException;

public class LocalhostDebianDeployment extends Deployment {
  final DeploymentDetails deploymentDetails;

  public LocalhostDebianDeployment(DeploymentDetails deploymentDetails) {
    this.deploymentDetails = deploymentDetails;
  }

  @Override
  public DeploymentType deploymentType() {
    return DeploymentType.LocalhostDebian;
  }

  @Override
  public Object getService(EndpointType type) {
    String endpoint;
    switch (type) {
      case CLOUDDRIVER:
        Service clouddriver = getEndpoints().getServices().getClouddriver();
        endpoint = clouddriver.getAddress() + ":" + clouddriver.getPort();
        break;
      default:
        throw new IllegalArgumentException("Service for " + type + " not found");
    }

    return serviceFactory.createService(endpoint, type);
  }

  @Override
  public SpinnakerEndpoints getEndpoints() {
    return deploymentDetails.getEndpoints();
  }

  @Override
  public void deploy() {
    String pinFormat = "Package: spinnaker-%s\n"
        + "Pin: version %s\n"
        + "Pin-Priority: 1001\n";

    StringBuilder pinContents = new StringBuilder();

    deploymentDetails.getGenerateResult().getArtifactVersions().forEach((k, v) -> {
      pinContents.append(String.format(pinFormat, k.getName(), v));
    });

    AtomicFileWriter fileWriter = null;

    try {
      fileWriter = new AtomicFileWriter("/etc/apt/preferences.d/pin-spin");
      fileWriter.write(pinContents.toString());
    } catch (IOException e) {
      throw new HalException(new ConfigProblemBuilder(Severity.ERROR, "Failed to write debian pin file: " + e).build());
    } finally {
      if (fileWriter != null) {
        fileWriter.close();
      }
    }
  }
}

@@ -1029,16 +1029,86 @@
 verity;%0A
+import com.netflix.spinnaker.halyard.core.tasks.v1.DaemonTaskHandler;%0A
 import c
@@ -2305,24 +2305,91 @@
  deploy() %7B%0A
+    DaemonTaskHandler.newStage(%22Generating apt-preferences file%22);%0A
     String p
@@ -2421,24 +2421,24 @@
 naker-%25s%5Cn%22%0A
-
         + %22P
@@ -2498,58 +2498,65 @@
     
-StringBuilder pinContents = new StringBuilder()
+AtomicFileWriter%5B%5D fileWriter = new AtomicFileWriter%5B1%5D
 ;%0A
-%0A
     
@@ -2645,130 +2645,94 @@
     
-pinContents.append(String.format(pinFormat, k.getName(), v));%0A    %7D);%0A%0A    AtomicFileWriter fileWriter = null;%0A%0A    try %7B%0A
+try %7B%0A        DaemonTaskHandler.log(%22Pinning %22 + k.getName() + %22 version to %22 + v);%0A  
     
@@ -2735,32 +2735,35 @@
       fileWriter
+%5B0%5D
  = new AtomicFil
@@ -2802,20 +2802,37 @@
 pin-spin
-%22
+-%22 + k.getName()
 );%0A
+  
       fi
@@ -2843,40 +2843,95 @@
 iter
+%5B0%5D
 .write(
-pinContents.toString
+String.format(pinFormat, k.getName(), v));%0A        fileWriter%5B0%5D.commit
 ()
-)
 ;%0A
+  
     
@@ -2952,24 +2952,26 @@
 eption e) %7B%0A
+  
       throw 
@@ -3075,24 +3075,26 @@
 ).build());%0A
+  
     %7D finall
@@ -3103,16 +3103,18 @@
 %7B%0A      
+  
 if (file
@@ -3119,16 +3119,19 @@
 leWriter
+%5B0%5D
  != null
@@ -3134,32 +3134,34 @@
 null) %7B%0A        
+  
 fileWriter.close
@@ -3154,16 +3154,19 @@
 leWriter
+%5B0%5D
 .close()
@@ -3171,16 +3171,58 @@
 ();%0A
+          fileWriter%5B0%5D = null;%0A        %7D%0A
       %7D%0A
     
@@ -3217,20 +3217,22 @@
       %7D%0A
-
     %7D
+);
 %0A  %7D%0A%7D%0A

Fix debian install pinning. The preferences need to be separated (#176)