package com.bonus.mq.rabbit.tx;

import com.bonus.mq.rabbit.RabbitPropertiesExt;
import com.bonus.mq.tx.TxMessageManager;
import com.google.common.collect.Lists;

import javax.sql.DataSource;
import java.sql.*;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

public class DataSourceTxMessageManager implements TxMessageManager {
   private final DataSource dataSource;

   public DataSourceTxMessageManager(DataSource dataSource) {
      this.dataSource = dataSource;
   }

   public void saveTxMessage(RabbitPropertiesExt.RabbitMessage message) throws SQLException {
      try {
         Connection connection = this.dataSource.getConnection();

         try {
            PreparedStatement statement = connection.prepareStatement("INSERT INTO mq_tx_local(id,exchange,routing_key,payload,delay,create_time) VALUES(?,?,?,?,?,?)");

            try {
               statement.setString(1, message.getId());
               statement.setString(2, message.getExchange());
               statement.setString(3, message.getRoutingKey());
               statement.setString(4, message.getPayload());
               if (message.getDelay() == null) {
                  statement.setNull(5, -5);
               } else {
                  statement.setLong(5, message.getDelay());
               }

               statement.setTimestamp(6, Timestamp.valueOf(message.getCreateTime() == null ? LocalDateTime.now() : message.getCreateTime()));
               statement.execute();
            } catch (Throwable var8) {
               if (statement != null) {
                  try {
                     statement.close();
                  } catch (Throwable var7) {
                     var8.addSuppressed(var7);
                  }
               }

               throw var8;
            }

            if (statement != null) {
               statement.close();
            }
         } catch (Throwable var9) {
            if (connection != null) {
               try {
                  connection.close();
               } catch (Throwable var6) {
                  var9.addSuppressed(var6);
               }
            }

            throw var9;
         }

         if (connection != null) {
            connection.close();
         }

      } catch (Throwable var10) {
         throw var10;
      }
   }

   public void afterSendSuccess(String messageId) throws SQLException {
      try {
         Connection connection = this.dataSource.getConnection();

         try {
            Statement statement = connection.createStatement();

            try {
               statement.execute("DELETE FROM mq_tx_local WHERE id='" + messageId + "'");
            } catch (Throwable var8) {
               if (statement != null) {
                  try {
                     statement.close();
                  } catch (Throwable var7) {
                     var8.addSuppressed(var7);
                  }
               }

               throw var8;
            }

            if (statement != null) {
               statement.close();
            }
         } catch (Throwable var9) {
            if (connection != null) {
               try {
                  connection.close();
               } catch (Throwable var6) {
                  var9.addSuppressed(var6);
               }
            }

            throw var9;
         }

         if (connection != null) {
            connection.close();
         }

      } catch (Throwable var10) {
         throw var10;
      }
   }

   public void afterSendFailed(String messageId, String cause) throws SQLException {
      try {
         Connection connection = this.dataSource.getConnection();

         label76: {
            try {
               Statement statement = connection.createStatement();

               label78: {
                  try {
                     statement.execute("UPDATE mq_tx_local SET times=times+1 WHERE id='" + messageId + "'");
                     if (statement.getUpdateCount() <= 0) {
                        statement.execute("DELETE FROM mq_tx_local WHERE id='" + messageId + "'");
                        break label78;
                     }
                  } catch (Throwable var9) {
                     if (statement != null) {
                        try {
                           statement.close();
                        } catch (Throwable var8) {
                           var9.addSuppressed(var8);
                        }
                     }

                     throw var9;
                  }

                  if (statement != null) {
                     statement.close();
                  }
                  break label76;
               }

               if (statement != null) {
                  statement.close();
               }
            } catch (Throwable var10) {
               if (connection != null) {
                  try {
                     connection.close();
                  } catch (Throwable var7) {
                     var10.addSuppressed(var7);
                  }
               }

               throw var10;
            }

            if (connection != null) {
               connection.close();
            }

            return;
         }

         if (connection != null) {
            connection.close();
         }

      } catch (Throwable var11) {
         throw var11;
      }
   }

   public void afterRollback(String messageId) throws SQLException {
      try {
         Connection connection = this.dataSource.getConnection();

         try {
            Statement statement = connection.createStatement();

            try {
               statement.execute("DELETE FROM mq_tx_local WHERE id='" + messageId + "'");
            } catch (Throwable var8) {
               if (statement != null) {
                  try {
                     statement.close();
                  } catch (Throwable var7) {
                     var8.addSuppressed(var7);
                  }
               }

               throw var8;
            }

            if (statement != null) {
               statement.close();
            }
         } catch (Throwable var9) {
            if (connection != null) {
               try {
                  connection.close();
               } catch (Throwable var6) {
                  var9.addSuppressed(var6);
               }
            }

            throw var9;
         }

         if (connection != null) {
            connection.close();
         }

      } catch (Throwable var10) {
         throw var10;
      }
   }

   public List<RabbitPropertiesExt.RabbitMessage> failedMessage() throws SQLException {
      try {
         Connection connection = this.dataSource.getConnection();

         ArrayList var12;
         try {
            Statement statement = connection.createStatement();

            try {
               ResultSet resultSet = statement.executeQuery("SELECT id,exchange,routing_key,payload,delay,create_time FROM mq_tx_local WHERE times < 10 LIMIT 1000");
               List<RabbitPropertiesExt.RabbitMessage> messages = Lists.newArrayList();

               while(resultSet.next()) {
                  RabbitPropertiesExt.RabbitMessage message = new RabbitPropertiesExt.RabbitMessage();
                  message.setId(resultSet.getString("id"));
                  message.setExchange(resultSet.getString("exchange"));
                  message.setRoutingKey(resultSet.getString("routing_key"));
                  message.setPayload(resultSet.getString("payload"));
                  Object delay = resultSet.getObject("delay");
                  if (delay != null) {
                     message.setDelay(resultSet.getLong("delay"));
                  }

                  message.setCreateTime(resultSet.getTimestamp("create_time").toLocalDateTime());
                  messages.add(message);
               }

               var12 = (ArrayList) messages;
            } catch (Throwable var9) {
               if (statement != null) {
                  try {
                     statement.close();
                  } catch (Throwable var8) {
                     var9.addSuppressed(var8);
                  }
               }

               throw var9;
            }

            if (statement != null) {
               statement.close();
            }
         } catch (Throwable var10) {
            if (connection != null) {
               try {
                  connection.close();
               } catch (Throwable var7) {
                  var10.addSuppressed(var7);
               }
            }

            throw var10;
         }

         if (connection != null) {
            connection.close();
         }

         return var12;
      } catch (Throwable var11) {
         throw var11;
      }
   }

   public void afterPropertiesSet() throws SQLException {
      try {
         Connection connection = this.dataSource.getConnection();

         try {
            Statement statement = connection.createStatement();

            try {
               statement.execute("CREATE TABLE IF NOT EXISTS `mq_tx_local` (\n  `id` varchar(50) NOT NULL,\n  `exchange` varchar(100) DEFAULT NULL,\n  `routing_key` varchar(200) NOT NULL,\n  `payload` longtext NOT NULL,\n  `delay` bigint DEFAULT NULL,\n  `times` int DEFAULT 0,\n  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,\n  PRIMARY KEY (`id`),\n  KEY `mq_tx_local_times` (`times`)\n)");
            } catch (Throwable var7) {
               if (statement != null) {
                  try {
                     statement.close();
                  } catch (Throwable var6) {
                     var7.addSuppressed(var6);
                  }
               }

               throw var7;
            }

            if (statement != null) {
               statement.close();
            }
         } catch (Throwable var8) {
            if (connection != null) {
               try {
                  connection.close();
               } catch (Throwable var5) {
                  var8.addSuppressed(var5);
               }
            }

            throw var8;
         }

         if (connection != null) {
            connection.close();
         }

      } catch (Throwable var9) {
         throw var9;
      }
   }
}
