content: package com.genersoft.iot.vmp.jt1078.proc.request;
  
  import com.genersoft.iot.vmp.common.CivilCodePo;
  import com.genersoft.iot.vmp.jt1078.annotation.MsgId;
  import com.genersoft.iot.vmp.jt1078.bean.JTDevice;
  import com.genersoft.iot.vmp.jt1078.event.DeviceUpdateEvent;
  import com.genersoft.iot.vmp.jt1078.proc.Header;
  import com.genersoft.iot.vmp.jt1078.proc.response.J8100;
  import com.genersoft.iot.vmp.jt1078.proc.response.Rs;
  import com.genersoft.iot.vmp.jt1078.service.Ijt1078Service;
  import com.genersoft.iot.vmp.jt1078.session.Session;
  import com.genersoft.iot.vmp.utils.CivilCodeUtil;
  import com.genersoft.iot.vmp.utils.DateUtil;
  import io.netty.buffer.ByteBuf;
  import lombok.extern.slf4j.Slf4j;
  import org.springframework.context.ApplicationEvent;
  
  import java.io.UnsupportedEncodingException;
  import java.nio.charset.Charset;
  import java.util.UUID;
  
  /**
   * 终端注册
   *
   * @author QingtaiJiang
   * @date 2023/4/27 18:06
   * @email qingtaij@163.com
   */
  @Slf4j
  @MsgId(id = "0100")
  public class J0100 extends Re {
  
      private JTDevice device;
      private JTDevice deviceForUpdate;
  
      @Override
      protected Rs decode0(ByteBuf buf, Header header, Session session) {
          Short version = header.getVersion();
          device = new JTDevice();
          device.setProvinceId(buf.readUnsignedShort() + "");
          if (version >= 1) {
              device.setCityId(buf.readUnsignedShort() + "");
              // decode as 2019
              device.setMakerId(buf.readCharSequence(11, Charset.forName("GBK"))
                      .toString().trim());
  
              device.setModel(buf.readCharSequence(30, Charset.forName("GBK"))
                      .toString().trim());
  
              device.setTerminalId(buf.readCharSequence(30, Charset.forName("GBK"))
                      .toString().trim());
  
              device.setPlateColor(buf.readByte());
              device.setPlateNo(buf.readCharSequence(buf.readableBytes(), Charset.forName("GBK"))
                      .toString().trim());
          } else {
              // decode as 2013
              device.setCityId(buf.readUnsignedShort() + "");
              // decode as 2019
              byte[] bytes5 = new byte[5];
              buf.readBytes(bytes5);
              device.setMakerId(new String(bytes5).trim());
  
              byte[] bytes20 = new byte[20];
              buf.readBytes(bytes20);
              device.setModel(new String(bytes20).trim());
  
              byte[] bytes7 = new byte[7];
              buf.readBytes(bytes7);
              device.setTerminalId(new String(bytes7).trim());
  
              device.setPlateColor(buf.readByte());
              byte[] plateColorBytes = new byte[buf.readableBytes()];
              buf.readBytes(plateColorBytes);
              try {
                  device.setPlateNo(new String(plateColorBytes, "GBK").trim());
              } catch (UnsupportedEncodingException e) {
                  throw new RuntimeException(e);
              }
          }
          return null;
      }
  
      @Override
      protected Rs handler(Header header, Session session, Ijt1078Service service) {
          J8100 j8100 = new J8100();
          j8100.setRespNo(header.getSn());
          // 从数据库判断这个设备是否合法
          deviceForUpdate = service.getDevice(header.getPhoneNumber());
          if (deviceForUpdate != null) {
              j8100.setResult(J8100.SUCCESS);
              String authenticationCode = UUID.randomUUID().toString();
              j8100.setCode(authenticationCode);
              session.setAuthenticationCode(authenticationCode);
              deviceForUpdate.setStatus(true);
              deviceForUpdate.setProvinceId(device.getProvinceId());
              deviceForUpdate.setRegisterTime(DateUtil.getNow());
              CivilCodePo provinceCivilCodePo = CivilCodeUtil.INSTANCE.get(device.getProvinceId());
              if (provinceCivilCodePo != null) {
                  deviceForUpdate.setProvinceText(provinceCivilCodePo.getName());
              }
              deviceForUpdate.setCityId(device.getCityId());
              CivilCodePo cityCivilCodePo = CivilCodeUtil.INSTANCE.get(device.getProvinceId() +
                      String.format("%04d", Integer.parseInt(device.getCityId())));
              if (cityCivilCodePo != null) {
                  deviceForUpdate.setCityText(cityCivilCodePo.getName());
              }
              deviceForUpdate.setModel(device.getModel());
              deviceForUpdate.setMakerId(device.getMakerId());
              deviceForUpdate.setTerminalId(device.getTerminalId());
              // TODO 支持直接展示车牌颜色的描述
              deviceForUpdate.setPlateColor(device.getPlateColor());
              deviceForUpdate.setPlateNo(device.getPlateNo());
              log.info("[JT-注册成功] 设备： {}", deviceForUpdate);
          }else {
              log.info("[JT-注册失败] 未授权设备： {}", header.getPhoneNumber());
              j8100.setResult(J8100.FAIL);
              // 断开连接，清理资源
              if (session.isRegistered()) {
                  session.unregister();
              }
          }
          return j8100;
      }
  
      @Override
      public ApplicationEvent getEvent() {
          DeviceUpdateEvent registerEvent = new DeviceUpdateEvent(this);
          registerEvent.setDevice(deviceForUpdate);
          return registerEvent;
      }
  }
  