/*
 * 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.accumulo.monitor.rest.problems;

import static org.apache.accumulo.monitor.util.ParameterValidator.ALPHA_NUM_REGEX_TABLE_ID;
import static org.apache.accumulo.monitor.util.ParameterValidator.PROBLEM_TYPE_REGEX;
import static org.apache.accumulo.monitor.util.ParameterValidator.RESOURCE_REGEX;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;

import javax.inject.Inject;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;

import org.apache.accumulo.core.clientImpl.Tables;
import org.apache.accumulo.core.data.TableId;
import org.apache.accumulo.monitor.Monitor;
import org.apache.accumulo.server.problems.ProblemReport;
import org.apache.accumulo.server.problems.ProblemReports;
import org.apache.accumulo.server.problems.ProblemType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Generates a problem summary and details as a JSON object
 *
 * @since 2.0.0
 */
@Path("/problems")
@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
public class ProblemsResource {

  @Inject
  private Monitor monitor;

  /**
   * Generates a list with the problem summary
   *
   * @return problem summary list
   */
  @GET
  @Path("summary")
  public ProblemSummary getSummary() {

    ProblemSummary problems = new ProblemSummary();

    if (monitor.getProblemException() == null) {
      for (Entry<TableId,Map<ProblemType,Integer>> entry : monitor.getProblemSummary().entrySet()) {
        Integer readCount = null, writeCount = null, loadCount = null;

        for (ProblemType pt : ProblemType.values()) {
          Integer pcount = entry.getValue().get(pt);
          if (pt.equals(ProblemType.FILE_READ)) {
            readCount = pcount;
          } else if (pt.equals(ProblemType.FILE_WRITE)) {
            writeCount = pcount;
          } else if (pt.equals(ProblemType.TABLET_LOAD)) {
            loadCount = pcount;
          }
        }

        String tableName = Tables.getPrintableTableInfoFromId(monitor.getContext(), entry.getKey());

        problems.addProblemSummary(new ProblemSummaryInformation(tableName, entry.getKey(),
            readCount, writeCount, loadCount));
      }
    }
    return problems;
  }

  /**
   * REST call to clear problem reports from a table
   *
   * @param tableID
   *          Table ID to clear problems
   */
  @POST
  @Consumes(MediaType.TEXT_PLAIN)
  @Path("summary")
  public void clearTableProblems(
      @QueryParam("s") @NotNull @Pattern(regexp = ALPHA_NUM_REGEX_TABLE_ID) String tableID) {
    Logger log = LoggerFactory.getLogger(Monitor.class);
    try {
      ProblemReports.getInstance(monitor.getContext()).deleteProblemReports(TableId.of(tableID));
    } catch (Exception e) {
      log.error("Failed to delete problem reports for table "
          + (tableID.isEmpty() ? "" : sanitize(tableID)), e);
    }
  }

  /**
   * Generates a list of the problem details as a JSON object
   *
   * @return problem details list
   */
  @GET
  @Path("details")
  public ProblemDetail getDetails() {

    ProblemDetail problems = new ProblemDetail();

    if (monitor.getProblemException() == null) {
      for (Entry<TableId,Map<ProblemType,Integer>> entry : monitor.getProblemSummary().entrySet()) {
        ArrayList<ProblemReport> problemReports = new ArrayList<>();
        Iterator<ProblemReport> iter =
            entry.getKey() == null ? ProblemReports.getInstance(monitor.getContext()).iterator()
                : ProblemReports.getInstance(monitor.getContext()).iterator(entry.getKey());
        while (iter.hasNext()) {
          problemReports.add(iter.next());
        }
        for (ProblemReport pr : problemReports) {
          String tableName =
              Tables.getPrintableTableInfoFromId(monitor.getContext(), pr.getTableId());

          problems.addProblemDetail(
              new ProblemDetailInformation(tableName, entry.getKey(), pr.getProblemType().name(),
                  pr.getServer(), pr.getTime(), pr.getResource(), pr.getException()));
        }
      }
    }
    return problems;
  }

  /**
   * REST call to clear specific problem details
   *
   * @param tableID
   *          Table ID to clear
   * @param resource
   *          Resource to clear
   * @param ptype
   *          Problem type to clear
   */
  @POST
  @Consumes(MediaType.TEXT_PLAIN)
  @Path("details")
  public void clearDetailsProblems(
      @QueryParam("table") @NotNull @Pattern(regexp = ALPHA_NUM_REGEX_TABLE_ID) String tableID,
      @QueryParam("resource") @NotNull @Pattern(regexp = RESOURCE_REGEX) String resource,
      @QueryParam("ptype") @NotNull @Pattern(regexp = PROBLEM_TYPE_REGEX) String ptype) {
    Logger log = LoggerFactory.getLogger(Monitor.class);
    try {
      ProblemReports.getInstance(monitor.getContext()).deleteProblemReport(TableId.of(tableID),
          ProblemType.valueOf(ptype), resource);
    } catch (Exception e) {
      log.error("Failed to delete problem reports for table "
          + (tableID.isBlank() ? "" : sanitize(tableID)), e);
    }
  }

  /**
   * Prevent potential CRLF injection into logs from read in user data. See
   * https://find-sec-bugs.github.io/bugs.htm#CRLF_INJECTION_LOGS
   */
  private String sanitize(String msg) {
    return msg.replaceAll("[\r\n]", "");
  }

  @GET
  @Path("exception")
  public Exception getException() {
    return monitor.getProblemException();
  }

}
