/**
 * 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.metron.parsers.asa;

import com.google.common.collect.ImmutableMap;
import oi.thekraken.grok.api.Grok;
import oi.thekraken.grok.api.Match;
import oi.thekraken.grok.api.exception.GrokException;
import org.apache.metron.common.Constants;
import org.apache.metron.parsers.BasicParser;
import org.apache.metron.parsers.ParseException;
import org.apache.metron.parsers.utils.SyslogUtils;
import org.json.simple.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.time.Clock;
import java.time.ZoneId;
import java.util.*;
import java.util.Map.Entry;

public class BasicAsaParser extends BasicParser {

  protected static final Logger LOG = LoggerFactory.getLogger(BasicAsaParser.class);

  protected Clock deviceClock;
  private String syslogPattern = "%{CISCO_TAGGED_SYSLOG}";

  private Grok syslogGrok;

  private static final Map<String, String> patternMap = ImmutableMap.<String, String> builder()
      .put("ASA-2-106001", "CISCOFW106001")
      .put("ASA-2-106006", "CISCOFW106006_106007_106010")
      .put("ASA-2-106007", "CISCOFW106006_106007_106010")
      .put("ASA-2-106010", "CISCOFW106006_106007_106010")
      .put("ASA-3-106014", "CISCOFW106014")
      .put("ASA-6-106015", "CISCOFW106015")
      .put("ASA-1-106021", "CISCOFW106021")
      .put("ASA-4-106023", "CISCOFW106023")
      .put("ASA-5-106100", "CISCOFW106100")
      .put("ASA-6-110002", "CISCOFW110002")
      .put("ASA-6-302010", "CISCOFW302010")
      .put("ASA-6-302013", "CISCOFW302013_302014_302015_302016")
      .put("ASA-6-302014", "CISCOFW302013_302014_302015_302016")
      .put("ASA-6-302015", "CISCOFW302013_302014_302015_302016")
      .put("ASA-6-302016", "CISCOFW302013_302014_302015_302016")
      .put("ASA-6-302020", "CISCOFW302020_302021")
      .put("ASA-6-302021", "CISCOFW302020_302021")
      .put("ASA-6-305011", "CISCOFW305011")
      .put("ASA-3-313001", "CISCOFW313001_313004_313008")
      .put("ASA-3-313004", "CISCOFW313001_313004_313008")
      .put("ASA-3-313008", "CISCOFW313001_313004_313008")
      .put("ASA-4-313005", "CISCOFW313005")
      .put("ASA-4-402117", "CISCOFW402117")
      .put("ASA-4-402119", "CISCOFW402119")
      .put("ASA-4-419001", "CISCOFW419001")
      .put("ASA-4-419002", "CISCOFW419002")
      .put("ASA-4-500004", "CISCOFW500004")
      .put("ASA-6-602303", "CISCOFW602303_602304")
      .put("ASA-6-602304", "CISCOFW602303_602304")
      .put("ASA-7-710001", "CISCOFW710001_710002_710003_710005_710006")
      .put("ASA-7-710002", "CISCOFW710001_710002_710003_710005_710006")
      .put("ASA-7-710003", "CISCOFW710001_710002_710003_710005_710006")
      .put("ASA-7-710005", "CISCOFW710001_710002_710003_710005_710006")
      .put("ASA-7-710006", "CISCOFW710001_710002_710003_710005_710006")
      .put("ASA-6-713172", "CISCOFW713172")
      .put("ASA-4-733100", "CISCOFW733100")
      .put("ASA-6-305012", "CISCOFW305012")
      .put("ASA-7-609001", "CISCOFW609001")
      .put("ASA-7-609002", "CISCOFW609002")
      .put("ASA-5-713041", "CISCOFW713041")
      .build();

  private Map<String, Grok> grokers = new HashMap<String, Grok>(patternMap.size());

  @Override
  public void configure(Map<String, Object> parserConfig) {
    String timeZone = (String) parserConfig.get("deviceTimeZone");
    if (timeZone != null)
      deviceClock = Clock.system(ZoneId.of(timeZone));
    else {
      deviceClock = Clock.systemUTC();
      LOG.warn("[Metron] No device time zone provided; defaulting to UTC");
    }
  }

  private void addGrok(String key, String pattern) throws GrokException {
    Grok grok = new Grok();
    InputStream patternStream = this.getClass().getResourceAsStream("/patterns/asa");
    grok.addPatternFromReader(new InputStreamReader(patternStream));
    grok.compile("%{" + pattern + "}");
    grokers.put(key, grok);
  }

  @Override
  public void init() {
    syslogGrok = new Grok();
    InputStream syslogStream = this.getClass().getResourceAsStream("/patterns/asa");
    try {
      syslogGrok.addPatternFromReader(new InputStreamReader(syslogStream));
      syslogGrok.compile(syslogPattern);
    } catch (GrokException e) {
      LOG.error("[Metron] Failed to load grok patterns from jar", e);
      throw new RuntimeException(e.getMessage(), e);
    }

    for (Entry<String, String> pattern : patternMap.entrySet()) {
      try {
	addGrok(pattern.getKey(), pattern.getValue());
      } catch (GrokException e) {
	LOG.error("[Metron] Failed to load grok pattern %s for ASA tag %s", pattern.getValue(), pattern.getKey());
      }
    }

    LOG.info("[Metron] CISCO ASA Parser Initialized");
  }

  @Override
  public List<JSONObject> parse(byte[] rawMessage) {
    String logLine = "";
    String messagePattern = "";
    JSONObject metronJson = new JSONObject();
    List<JSONObject> messages = new ArrayList<>();
    Map<String, Object> syslogJson = new HashMap<String, Object>();

    try {
      logLine = new String(rawMessage, "UTF-8");
    } catch (UnsupportedEncodingException e) {
      LOG.error("[Metron] Could not read raw message", e);
      throw new RuntimeException(e.getMessage(), e);
    }

    try {
      LOG.debug("[Metron] Started parsing raw message: {}", logLine);
      Match syslogMatch = syslogGrok.match(logLine);
      syslogMatch.captures();
      if (!syslogMatch.isNull()) {
	syslogJson = syslogMatch.toMap();
	LOG.trace("[Metron] Grok CISCO ASA syslog matches: {}", syslogMatch.toJson());

	metronJson.put(Constants.Fields.ORIGINAL.getName(), logLine);
	metronJson.put(Constants.Fields.TIMESTAMP.getName(),
	    SyslogUtils.parseTimestampToEpochMillis((String) syslogJson.get("CISCOTIMESTAMP"), deviceClock));
	metronJson.put("ciscotag", syslogJson.get("CISCOTAG"));
	metronJson.put("syslog_severity", SyslogUtils.getSeverityFromPriority((int) syslogJson.get("syslog_pri")));
	metronJson.put("syslog_facility", SyslogUtils.getFacilityFromPriority((int) syslogJson.get("syslog_pri")));

	if (syslogJson.get("syslog_host") != null) {
	  metronJson.put("syslog_host", syslogJson.get("syslog_host"));
	}
	if (syslogJson.get("syslog_prog") != null) {
	  metronJson.put("syslog_prog", syslogJson.get("syslog_prog"));
	}

      } else
	throw new RuntimeException(
	    String.format("[Metron] Message '%s' does not match pattern '%s'", logLine, syslogPattern));
    } catch (ParseException e) {
      LOG.error("[Metron] Could not parse message timestamp", e);
      throw new RuntimeException(e.getMessage(), e);
    } catch (RuntimeException e) {
      LOG.error(e.getMessage(), e);
      throw new RuntimeException(e.getMessage(), e);
    }

    try {
      messagePattern = (String) syslogJson.get("CISCOTAG");
      Grok asaGrok = grokers.get(messagePattern);

      if (asaGrok == null)
	LOG.info("[Metron] No pattern for ciscotag '{}'", syslogJson.get("CISCOTAG"));
      else {

	String messageContent = (String) syslogJson.get("message");
	Match messageMatch = asaGrok.match(messageContent);
	messageMatch.captures();
	if (!messageMatch.isNull()) {
	  Map<String, Object> messageJson = messageMatch.toMap();
	  LOG.trace("[Metron] Grok CISCO ASA message matches: {}", messageMatch.toJson());

	  String src_ip = (String) messageJson.get("src_ip");
	  if (src_ip != null)
	    metronJson.put(Constants.Fields.SRC_ADDR.getName(), src_ip);

	  Integer src_port = (Integer) messageJson.get("src_port");
	  if (src_port != null)
	    metronJson.put(Constants.Fields.SRC_PORT.getName(), src_port);

	  String dst_ip = (String) messageJson.get("dst_ip");
	  if (dst_ip != null)
	    metronJson.put(Constants.Fields.DST_ADDR.getName(), dst_ip);

	  Integer dst_port = (Integer) messageJson.get("dst_port");
	  if (dst_port != null)
	    metronJson.put(Constants.Fields.DST_PORT.getName(), dst_port);

	  String protocol = (String) messageJson.get("protocol");
	  if (protocol != null)
	    metronJson.put(Constants.Fields.PROTOCOL.getName(), protocol.toLowerCase());

	  String action = (String) messageJson.get("action");
	  if (action != null)
	    metronJson.put("action", action.toLowerCase());
	} else
	  LOG.warn("[Metron] Message '{}' did not match pattern for ciscotag '{}'", logLine,
	      syslogJson.get("CISCOTAG"));
      }

      LOG.debug("[Metron] Final normalized message: {}", metronJson.toString());

    } catch (RuntimeException e) {
      LOG.error(e.getMessage(), e);
      throw new RuntimeException(e.getMessage(), e);
    }

    messages.add(metronJson);
    return messages;
  }
}
