/*
 * Copyright 2013-present Facebook, 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.facebook.buck.httpserver;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.net.MediaType;
import com.google.template.soy.SoyFileSet;
import com.google.template.soy.data.SoyMapData;
import com.google.template.soy.tofu.SoyTofu;

import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.handler.AbstractHandler;

import java.io.IOException;
import java.net.URL;

import javax.annotation.Nullable;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * {@link Handler} that provides a response by populating a Soy template.
 */
class TemplateHandler extends AbstractHandler {

  /**
   * Whether to re-parse the templates for this handler on every request.
   * <p>
   * Should be set to {@code false} when checked in, but it is convenient to set this to
   * {@code true} in development.
   */
  private static final boolean DEBUG = Boolean.getBoolean("buck.soy.debug");

  private final TemplateHandlerDelegate delegate;

  /**
   * This field is set lazily by {@link #createAndMaybeCacheSoyTofu()}.
   */
  @Nullable
  private volatile SoyTofu tofu;

  protected TemplateHandler(TemplateHandlerDelegate templateBasedHandler) {
    this.delegate = templateBasedHandler;
  }

  /**
   * Handles a request. Invokes {@link TemplateHandlerDelegate#getTemplateForRequest(Request)} to
   * get the template and {@link TemplateHandlerDelegate#getDataForRequest(Request)} to get the
   * template data, and then combines them to produce the response.
   */
  @Override
  public void handle(String target,
      Request baseRequest,
      HttpServletRequest request,
      HttpServletResponse response)
      throws IOException, ServletException {
    String html = createHtmlForResponse(baseRequest);
    if (html != null) {
      Responses.writeSuccessfulResponse(html, MediaType.HTML_UTF_8, baseRequest, response);
    } else {
      Responses.writeFailedResponse(baseRequest, response);
    }
  }

  @Nullable
  String createHtmlForResponse(Request baseRequest) throws IOException {
    String template = delegate.getTemplateForRequest(baseRequest);
    SoyTofu.Renderer renderer = createAndMaybeCacheSoyTofu().newRenderer(template);

    SoyMapData data = delegate.getDataForRequest(baseRequest);
    if (data != null) {
      renderer.setData(data);
      return renderer.render();
    } else {
      return null;
    }
  }

  @VisibleForTesting
  TemplateHandlerDelegate getDelegate() {
    return delegate;
  }

  /**
   * Returns the {@link SoyTofu} for {@link TemplateHandlerDelegate#getTemplates()}. If
   * {@link #DEBUG} is {@code false}, then the result will be cached because {@link SoyTofu} objects
   * can be expensive to construct.
   */
  private SoyTofu createAndMaybeCacheSoyTofu() {
    // In debug mode, create a new SoyTofu object for each request. This makes it possible to test
    // new versions of the templates without restarting buckd.
    if (DEBUG) {
      return createSoyTofu();
    }

    // In production, cache the SoyTofu object for efficiency.
    if (tofu != null) {
      return tofu;
    }

    synchronized (this) {
      if (tofu == null) {
        tofu = createSoyTofu();
      }
    }
    return tofu;
  }

  /** Creates the {@link SoyTofu} for {@link TemplateHandlerDelegate#getTemplates()}. */
  private SoyTofu createSoyTofu() {
    SoyFileSet.Builder builder = SoyFileSet.builder();
    for (String soyFile : delegate.getTemplates()) {
      URL url = delegate.getClass().getResource(soyFile);
      builder.add(url);
    }
    return builder.build().compileToTofu();
  }
}
