// Copyright (C) 2015 The Android Open Source Project
//
// 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.google.gerrit.httpd.raw;

import com.google.gwtexpui.linker.server.UserAgentRule;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Set;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

class RecompileGwtUiFilter implements Filter {
  private final boolean gwtuiRecompile =
      System.getProperty("gerrit.disable-gwtui-recompile") == null;
  private final UserAgentRule rule = new UserAgentRule();
  private final Set<String> uaInitialized = new HashSet<>();
  private final Path unpackedWar;
  private final BazelBuild builder;

  private String lastAgent;
  private long lastTime;

  RecompileGwtUiFilter(BazelBuild builder, Path unpackedWar) {
    this.builder = builder;
    this.unpackedWar = unpackedWar;
  }

  @Override
  public void doFilter(ServletRequest request, ServletResponse res, FilterChain chain)
      throws IOException, ServletException {
    String agent = rule.select((HttpServletRequest) request);
    if (unpackedWar != null && (gwtuiRecompile || !uaInitialized.contains(agent))) {
      BazelBuild.Label label = builder.gwtZipLabel(agent);
      File zip = builder.targetPath(label).toFile();

      synchronized (this) {
        try {
          builder.build(label);
        } catch (BazelBuild.BuildFailureException e) {
          e.display(label.toString(), (HttpServletResponse) res);
          return;
        }

        if (!agent.equals(lastAgent) || lastTime != zip.lastModified()) {
          lastAgent = agent;
          lastTime = zip.lastModified();
          unpack(zip, unpackedWar.toFile());
        }
      }
      uaInitialized.add(agent);
    }
    chain.doFilter(request, res);
  }

  @Override
  public void init(FilterConfig config) {}

  @Override
  public void destroy() {}

  private static void unpack(File srcwar, File dstwar) throws IOException {
    try (ZipFile zf = new ZipFile(srcwar)) {
      final Enumeration<? extends ZipEntry> e = zf.entries();
      while (e.hasMoreElements()) {
        final ZipEntry ze = e.nextElement();
        final String name = ze.getName();

        if (ze.isDirectory()
            || name.startsWith("WEB-INF/")
            || name.startsWith("META-INF/")
            || name.startsWith("com/google/gerrit/launcher/")
            || name.equals("Main.class")) {
          continue;
        }

        final File rawtmp = new File(dstwar, name);
        mkdir(rawtmp.getParentFile());
        rawtmp.deleteOnExit();

        try (OutputStream rawout = Files.newOutputStream(rawtmp.toPath());
            InputStream in = zf.getInputStream(ze)) {
          final byte[] buf = new byte[4096];
          int n;
          while ((n = in.read(buf, 0, buf.length)) > 0) {
            rawout.write(buf, 0, n);
          }
        }
      }
    }
  }

  private static void mkdir(File dir) throws IOException {
    if (!dir.isDirectory()) {
      mkdir(dir.getParentFile());
      if (!dir.mkdir()) {
        throw new IOException("Cannot mkdir " + dir.getAbsolutePath());
      }
      dir.deleteOnExit();
    }
  }
}
