/*
 * Copyright (C) 2017 Red Soft Corporation.
 *
 * This file is part of Red nCore.
 *
 * Red nCore is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2, or (at your option)
 * any later version.
 *
 * Red nCore 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
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Red nCore; see the file COPYING. If not, write to the
 * Red Soft Corporation, 117105, Russia, Moscow, Nagornyy proyezd, 5.
 *
 * Linking this library statically or dynamically with other modules is
 * making a combined work based on this library. Thus, the terms and
 * conditions of the GNU General Public License cover the whole
 * combination.
 *
 * As a special exception, the copyright holders of this library give you
 * permission to link this library with independent modules to produce an
 * executable, regardless of the license terms of these independent
 * modules, and to copy and distribute the resulting executable under
 * terms of your choice, provided that you also meet, for each linked
 * independent module, the terms and conditions of the license of that
 * module. An independent module is a module which is not derived from
 * or based on this library. If you modify this library, you may extend
 * this exception to your version of the library, but you are not
 * obligated to do so. If you do not wish to do so, delete this
 * exception statement from your version.
 */

package biz.redsoft.sample;

import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;

import javax.servlet.ServletException;

import org.apache.catalina.LifecycleException;
import org.apache.catalina.Server;
import org.apache.catalina.WebResourceRoot;
import org.apache.catalina.core.StandardContext;
import org.apache.catalina.startup.Tomcat;
import org.apache.catalina.webresources.DirResourceSet;
import org.apache.catalina.webresources.FileResourceSet;
import org.apache.catalina.webresources.StandardRoot;
import org.apache.tomcat.util.scan.StandardJarScanner;


public class TomcatStarter {
  private String contextPath = "/ncore";
  private int port = 8080;

  private int shutdownPort = 8020;
  private String shutdownCommand = "SHUTDOWN";

  public void start() throws ServletException, LifecycleException {
    System.setProperty("catalina.home", new File(".").getAbsolutePath());
    final Tomcat tomcat = new Tomcat();
    tomcat.setPort(port);
    tomcat.setBaseDir(".");
    tomcat.getHost().setAppBase(".");
    tomcat.getConnector(); // initialize standard HTTP 1.1 connector
    tomcat.enableNaming();
    final Server server = tomcat.getServer();
    server.setPort(shutdownPort);
    server.setShutdown(shutdownCommand);
    final StandardContext webContext = (StandardContext) tomcat.addWebapp(contextPath, "src/main/webapp");
    webContext.setUseNaming(true);
    final WebResourceRoot resources = new StandardRoot(webContext);
    //aliases to resources
    final String base = ap("");
    resources.addPreResources(new DirResourceSet(resources, "/META-INF/resources", ap("src/main/resources"), "/META-INF/resources"));
    //resources.addPreResources(new DirResourceSet(resources, "/WEB-INF/classes/export_templates", base, "/export_templates"));
    if (new File(base, "ncore-properties-local.xml").exists())
      resources.addPreResources(new FileResourceSet(resources, "/WEB-INF/ncore-properties-local.xml", base, "/ncore-properties-local.xml"));
    //resources.addPreResources(new FileResourceSet(resources, "/WEB-INF/ncore-properties-local-openid.xml", base, "/ncore-properties-local-openid.xml"));
    resources.addPreResources(new FileResourceSet(resources, "/WEB-INF/logback.xml", base, "/logback.xml"));
    webContext.setResources(resources);
    // IDEA не всегда корректно формирует пути. Отключим проверку ресурсов.
    ((StandardJarScanner)webContext.getJarScanner()).setScanClassPath(false);
    webContext.setWorkDir("build/tomcat/work");
    tomcat.start();
    server.await();
    tomcat.stop();
  }

  private String ap(String s) {
    return new File(s).getAbsolutePath();
  }

  public void stop() throws IOException {
    final InetAddress serverAddress = InetAddress.getByName("localhost");
    final Socket socket = new Socket(serverAddress, shutdownPort);
    try (OutputStream os = socket.getOutputStream()) {
      final byte[] buffer = shutdownCommand.getBytes();
      os.write(buffer, 0, buffer.length);
      os.flush();
    }
  }

  public static void main(String[] args) throws ServletException, LifecycleException, IOException {
    if (args.length > 0) {
      String command = args[0];
      if ("start".equals(command))
        new TomcatStarter().start();
      else if ("stop".equals(command))
        new TomcatStarter().stop();
    }
  }
}
