/*
 * 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.spinnaker.v1.service;


import com.netflix.spinnaker.halyard.config.model.v1.node.DeploymentConfiguration;
import com.netflix.spinnaker.halyard.config.model.v1.security.UiSecurity;
import com.netflix.spinnaker.halyard.deploy.spinnaker.v1.SpinnakerArtifact;
import com.netflix.spinnaker.halyard.deploy.spinnaker.v1.SpinnakerRuntimeSettings;
import com.netflix.spinnaker.halyard.deploy.spinnaker.v1.profile.*;
import com.netflix.spinnaker.halyard.deploy.spinnaker.v1.profile.deck.ApachePassphraseProfileFactory;
import com.netflix.spinnaker.halyard.deploy.spinnaker.v1.profile.deck.ApachePortsProfileFactory;
import com.netflix.spinnaker.halyard.deploy.spinnaker.v1.profile.deck.ApacheSpinnakerProfileFactory;
import com.netflix.spinnaker.halyard.deploy.spinnaker.v1.profile.deck.DeckProfileFactory;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.nio.file.Paths;
import java.util.*;

@EqualsAndHashCode(callSuper = true)
@Data
@Component
abstract public class DeckService extends SpinnakerService<DeckService.Deck> {
  @Autowired
  DeckProfileFactory deckProfileFactory;

  @Autowired
  ApachePassphraseProfileFactory apachePassphraseProfileFactory;

  @Autowired
  ApachePortsProfileFactory apachePortsProfileFactory;

  @Autowired
  ApacheSpinnakerProfileFactory apacheSpinnakerProfileFactory;

  @Override
  public Class<Deck> getEndpointClass() {
    return Deck.class;
  }

  @Override
  public SpinnakerArtifact getArtifact() {
    return SpinnakerArtifact.DECK;
  }

  @Override
  public Type getType() {
    return Type.DECK;
  }

  @Override
  public List<Profile> getProfiles(DeploymentConfiguration deploymentConfiguration, SpinnakerRuntimeSettings endpoints) {
    List<Profile> result = new ArrayList<>();
    String htmlPath = "/opt/deck/html/";
    String apache2Path = "/etc/apache2/";
    String sitePath = "/etc/apache2/sites-available/";
    String filename = "settings.js";
    String path = Paths.get(htmlPath, filename).toString();
    result.add(deckProfileFactory.getProfile(filename, path, deploymentConfiguration, endpoints));

    filename = "passphrase";
    path = Paths.get(apache2Path, filename).toString();
    result.add(apachePassphraseProfileFactory.getProfile("apache2/" + filename, path, deploymentConfiguration, endpoints).setExecutable(true));

    filename = "ports.conf";
    path = Paths.get(apache2Path, filename).toString();
    result.add(apachePortsProfileFactory.getProfile("apache2/" + filename, path, deploymentConfiguration, endpoints));

    filename = "spinnaker.conf";
    path = Paths.get(sitePath, filename).toString();
    result.add(apacheSpinnakerProfileFactory.getProfile("apache2/" + filename, path, deploymentConfiguration, endpoints));

    return result;
  }

  protected DeckService() {
    super();
  }

  public interface Deck { }

  @EqualsAndHashCode(callSuper = true)
  @Data
  public static class Settings extends ServiceSettings {
    Integer port = 9000;
    String address = "localhost";
    String host = "0.0.0.0";
    String scheme = "http";
    String healthEndpoint = null;
    Boolean enabled = true;
    Boolean safeToUpdate = true;
    Boolean monitored = false;
    Boolean sidecar = false;
    Integer targetSize = 1;
    Map<String, String> env = new HashMap<>();

    public Settings() {}

    public Settings(UiSecurity uiSecurity) {
      setOverrideBaseUrl(uiSecurity.getOverrideBaseUrl());
      if (uiSecurity.getSsl().isEnabled()) {
        scheme = "https";
      }
    }
  }

  @Override
  protected Optional<String> customProfileOutputPath(String profileName) {
    return Optional.empty();
  }
}

@@ -2061,16 +2061,56 @@
 ctory;%0A%0A
+  String htmlPath = %22/opt/deck/html/%22;%0A%0A
   @Overr
@@ -2105,32 +2105,32 @@
 %22;%0A%0A  @Override%0A
-
   public Class%3CD
@@ -2335,32 +2335,257 @@
 Type.DECK;%0A  %7D%0A%0A
+  protected Optional%3CString%3E customProfileOutputPath(String profileName) %7B%0A    if (profileName.equals(%22settings.js%22)) %7B%0A      return Optional.of(htmlPath + profileName);%0A    %7D else %7B%0A      return Optional.empty();%0A    %7D%0A  %7D%0A%0A
   @Override%0A  pu
@@ -2698,24 +2698,24 @@
 ndpoints) %7B%0A
+
     List%3CPro
@@ -2752,49 +2752,8 @@
 ();%0A
-    String htmlPath = %22/opt/deck/html/%22;%0A
     
@@ -4459,128 +4459,7 @@
 %0A  %7D
-%0A%0A  @Override%0A  protected Optional%3CString%3E customProfileOutputPath(String profileName) %7B%0A    return Optional.empty();%0A  %7D
 %0A%7D%0A

Allow settings.js to be overridden (#517)