package com.chenyang.nse.bussiness.tools.logger.dblog;

import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import com.chenyang.nse.bussiness.config.PropertiesLoaderUtils;
import com.chenyang.nse.bussiness.entity.vo.auditlog.DbAccessPojo;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.SocketAddress;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Properties;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import org.graylog2.syslog4j.server.SyslogServer;
import org.graylog2.syslog4j.server.SyslogServerConfigIF;
import org.graylog2.syslog4j.server.SyslogServerEventIF;
import org.graylog2.syslog4j.server.SyslogServerIF;
import org.graylog2.syslog4j.server.SyslogServerSessionEventHandlerIF;
import org.graylog2.syslog4j.server.impl.net.udp.UDPNetSyslogServerConfig;
import org.springframework.context.ApplicationContext;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

@Component
public class DblogService {
   protected static ApplicationContext applicationContext;
   private static Properties props = new Properties();
   private static String dbaccesslogpath = "";
   private static String dbrulelogpath = "";
   private static String dbAlertInterface = "";
   private static String HOST = "192.168.2.218";
   private static Integer PORT = 40000;
   private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
   private static FileOutputStream outputStream = null;

   private void receiveSyslogMessage() throws InterruptedException {
      Callable<ResponseEntity> responseEntityCallable = new Callable<ResponseEntity>() {
         public ResponseEntity call() throws Exception {
            System.out.println("审计日志服务端开启成功!");
            DblogService.this.startDbAudit();
            return ResponseEntity.ok("审计日志服务端开启成功!");
         }
      };
      ThreadFactory namedThreadFactory = (new ThreadFactoryBuilder()).setNameFormat("asyn-pool-%d").build();
      ExecutorService singleThreadPool = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue(1024), namedThreadFactory, new ThreadPoolExecutor.AbortPolicy());
      singleThreadPool.submit(responseEntityCallable);
   }

   private void startDbAudit() {
      SyslogServerIF server = SyslogServer.getInstance("udp");
      UDPNetSyslogServerConfig udpConfig = (UDPNetSyslogServerConfig)server.getConfig();
      udpConfig.setMaxMessageSize(10240);
      SyslogServerConfigIF config = server.getConfig();
      config.setHost(HOST);
      config.setPort(PORT);
      config.addEventHandler(new SyslogServerSessionEventHandlerIF() {
         public Object sessionOpened(SyslogServerIF syslogServerIF, SocketAddress socketAddress) {
            return null;
         }

         public void event(Object o, SyslogServerIF syslogServerIF, SocketAddress socketAddress, SyslogServerEventIF syslogServerEventIF) {
            String sendvalue = "{\"from\": \"" + socketAddress.toString().replace("/", "").split("\\:")[0] + "\",\"hostname\":\"" + syslogServerEventIF.getHost() + "\"," + syslogServerEventIF.getMessage().replace(syslogServerEventIF.getHost(), "\"message\":") + "}\n";
            File file = null;
            if (sendvalue.contains("\"logType\":\"0\"")) {
               file = new File(DblogService.dbaccesslogpath + File.separator + "access_log_" + DblogService.sdf.format(new Date()) + ".txt");
            } else if (sendvalue.contains("\"logType\":\"1\"")) {
               file = new File(DblogService.dbrulelogpath + File.separator + "rule_log_" + DblogService.sdf.format(new Date()) + ".txt");
            }

            if (sendvalue.contains("\"auditType\":\"0\"")) {
               JSONObject jo = JSONObject.parseObject(sendvalue);
               DbAccessPojo dbAccessPojo = (DbAccessPojo)JSONUtil.toBean(jo.getString("message"), DbAccessPojo.class);
               if (!ObjectUtils.isEmpty(dbAccessPojo)) {
                  DblogService.interfaceUtil(DblogService.dbAlertInterface, dbAccessPojo.getNoticetype(), dbAccessPojo.getNoticeid());
               }
            }

            if (!file.exists()) {
               try {
                  file.getParentFile().mkdirs();
                  file.createNewFile();
               } catch (Exception e) {
                  e.printStackTrace();
               }
            }

            try {
               DblogService.outputStream = new FileOutputStream(file, true);
               DblogService.outputStream.write(sendvalue.getBytes());
            } catch (Exception e) {
               e.printStackTrace();
            } finally {
               try {
                  DblogService.outputStream.close();
               } catch (IOException e) {
                  e.printStackTrace();
               }

            }

         }

         public void exception(Object o, SyslogServerIF syslogServerIF, SocketAddress socketAddress, Exception e) {
         }

         public void sessionClosed(Object o, SyslogServerIF syslogServerIF, SocketAddress socketAddress, boolean b) {
         }

         public void initialize(SyslogServerIF syslogServerIF) {
         }

         public void destroy(SyslogServerIF syslogServerIF) {
         }
      });
      SyslogServer.getThreadedInstance("udp");
   }

   public static void interfaceUtil(String path, String alarmtype, String alarmid) {
      try {
         path = path + "?alarmtype=" + alarmtype + "&alarmid=" + alarmid;
         URL url = new URL(path);
         HttpURLConnection conn = (HttpURLConnection)url.openConnection();
         PrintWriter out = null;
         conn.setRequestProperty("accept", "*/*");
         conn.setRequestProperty("connection", "Keep-Alive");
         conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
         conn.setDoOutput(true);
         conn.setDoInput(true);
         out = new PrintWriter(conn.getOutputStream());
         out.flush();
         InputStream is = conn.getInputStream();
         BufferedReader br = new BufferedReader(new InputStreamReader(is));
         String str = "";

         while((str = br.readLine()) != null) {
            System.out.println(str);
         }

         is.close();
         conn.disconnect();
         System.out.println("告警结束");
      } catch (Exception e) {
         e.printStackTrace();
      }

   }

   public static void main(String[] args) throws InterruptedException {
      (new DblogService()).receiveSyslogMessage();
   }

   public static void execute() throws InterruptedException {
      (new DblogService()).receiveSyslogMessage();
   }

   static {
      try {
         props = PropertiesLoaderUtils.loadAllProperties("config.properties");
         dbaccesslogpath = props.getProperty("dbaccesslogpath");
         dbrulelogpath = props.getProperty("dbrulelogpath");
         dbAlertInterface = props.getProperty("db_alert_interface");
         HOST = props.getProperty("dblogServerHost");
         PORT = Integer.parseInt(props.getProperty("dblogServerPort"));
      } catch (IOException e) {
         e.printStackTrace();
      } catch (Exception e) {
         e.printStackTrace();
      }

   }
}
