/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 org.apache.beam.runners.dataflow.worker.status;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson.JacksonFactory;
import com.google.api.client.util.Key;
import com.google.api.services.dataflow.Dataflow;
import com.google.api.services.dataflow.model.GetDebugConfigRequest;
import com.google.api.services.dataflow.model.GetDebugConfigResponse;
import com.google.api.services.dataflow.model.SendDebugCaptureRequest;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import org.apache.beam.runners.dataflow.options.DataflowWorkerHarnessOptions;
import org.apache.beam.vendor.guava.v26_0_jre.com.google.common.annotations.VisibleForTesting;
import org.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * DebugCapture encapsulates a simple periodic sender for HTML pages to the debug capture service.
 * It is dynamically configured by the service.
 */
public class DebugCapture {
  private static final Logger LOG = LoggerFactory.getLogger(DebugCapture.class);
  private static final JsonFactory JSON_FACTORY = new JacksonFactory();
  private static final String COMPONENT = "JavaHarness";
  // How often to refresh debug capture config.
  private static final long UPDATE_CONFIG_PERIOD_SEC = 60;
  // How often to check whether to send capture data.
  private static final long SEND_CAPTURE_PERIOD_SEC = 10;

  /** Config */
  public static class Config {
    @Key
    @JsonProperty("expire_timestamp_usec")
    public long expireTimestampUsec;

    @Key
    @JsonProperty("capture_frequency_usec")
    public long captureFrequencyUsec;
  }

  private static class Payload {
    @Key public List<Page> pages = new ArrayList<>();
  }

  private static class Page {
    public Page(String name, String content) {
      this.name = name;
      this.content = content;
    }

    // Implicitly read. Not a bug.
    @SuppressFBWarnings("URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD")
    @Key
    public String name;

    // Implicitly read. Not a bug.
    @SuppressFBWarnings("URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD")
    @Key
    public String content;
  }

  /** Interface for capturable components. */
  public interface Capturable {
    String pageName();

    void captureData(PrintWriter writer);
  }

  /** Manager */
  public static class Manager {
    private final Object lock = new Object();
    private final ObjectMapper mapper = new ObjectMapper();
    private String project, job, host, region;
    private Dataflow client = null;
    private ScheduledExecutorService executor = null;
    private List<Capturable> capturables;
    private boolean enabled;

    private long lastCaptureUsec = 0;
    @VisibleForTesting Config captureConfig = new Config();

    public Manager(DataflowWorkerHarnessOptions options, List<Capturable> capturables) {
      try {
        client = options.getDataflowClient();
      } catch (Exception e) {
        LOG.info("Failed to get dataflow client. Does not send debug capture data. ", e);
        return;
      }

      project = options.getProject();
      job = options.getJobId();
      host = options.getWorkerId();
      region = options.getRegion();
      this.capturables = capturables;
      enabled = !capturables.isEmpty();
    }

    @SuppressWarnings("FutureReturnValueIgnored")
    public void start() {
      if (!enabled) {
        return;
      }

      executor = Executors.newScheduledThreadPool(2);
      executor.scheduleAtFixedRate(
          this::updateConfig, 0, UPDATE_CONFIG_PERIOD_SEC, TimeUnit.SECONDS);
      executor.scheduleAtFixedRate(
          this::maybeSendCapture, 0, SEND_CAPTURE_PERIOD_SEC, TimeUnit.SECONDS);
    }

    public void stop() {
      if (executor != null) {
        executor.shutdown();
      }
    }

    @VisibleForTesting
    void updateConfig() {
      try {
        GetDebugConfigRequest request =
            new GetDebugConfigRequest().setComponentId(COMPONENT).setWorkerId(host);
        GetDebugConfigResponse response =
            this.client
                .projects()
                .locations()
                .jobs()
                .debug()
                .getConfig(project, region, job, request)
                .execute();
        Config config = mapper.readValue(response.getConfig(), Config.class);
        synchronized (lock) {
          captureConfig = config;
        }
      } catch (Exception e) {
        LOG.info("Does not update debug config", e);
      }
    }

    private boolean shouldSendCapture() {
      synchronized (lock) {
        long nowUsec = DateTime.now().getMillis() * 1000;
        if (captureConfig.expireTimestampUsec < nowUsec) {
          return false; // expired config
        }
        if (captureConfig.captureFrequencyUsec == 0) {
          return false; // disabled
        }
        return captureConfig.captureFrequencyUsec < (nowUsec - lastCaptureUsec);
      }
    }

    @VisibleForTesting
    void maybeSendCapture() {
      if (!shouldSendCapture()) {
        return;
      }

      try {
        Payload payload = new Payload();
        for (Capturable capturable : capturables) {
          StringWriter content = new StringWriter();
          PrintWriter writer = new PrintWriter(content);
          capturable.captureData(writer);
          writer.flush();
          payload.pages.add(new Page(capturable.pageName(), content.toString()));
        }

        SendDebugCaptureRequest request =
            new SendDebugCaptureRequest()
                .setComponentId(COMPONENT)
                .setWorkerId(host)
                .setData(JSON_FACTORY.toString(payload));
        this.client
            .projects()
            .locations()
            .jobs()
            .debug()
            .sendCapture(project, region, job, request)
            .execute();

        synchronized (lock) {
          lastCaptureUsec = DateTime.now().getMillis() * 1000;
        }
      } catch (Exception e) {
        LOG.info("Does not send debug capture data", e);
      }
    }
  }
}
