class TsFileDeserializer {

  @SuppressWarnings("squid:S3776") // Suppress high Cognitive Complexity warning
  public Object deserialize(List<String> columnNames, List<TypeInfo> columnTypes,
                            Writable writable, String deviceId) throws TsFileSerDeException {
    if(!(writable instanceof MapWritable)) {
      throw new TsFileSerDeException("Expecting a MapWritable");
    }

    if(row == null || row.size() != columnNames.size()) {
      row = new ArrayList<>(columnNames.size());
    } else {
      row.clear();
    }
    MapWritable mapWritable = (MapWritable) writable;
    if (!Objects.equals(mapWritable.get(new Text("device_id")).toString(), deviceId)) {
      return null;
    }

    LOG.debug("device_id: {}", mapWritable.get(new Text("device_id")).toString());
    LOG.debug("time_stamp: {}" , mapWritable.get(new Text("time_stamp")));

    for(int i = 0; i < columnNames.size(); i++) {
      TypeInfo columnType = columnTypes.get(i);
      String columnName = columnNames.get(i);
      Writable data = mapWritable.get(new Text(columnName));
      if (data == null || data instanceof NullWritable) {
        row.add(null);
        continue;
      }
      if (columnType.getCategory() != ObjectInspector.Category.PRIMITIVE) {
        throw new TsFileSerDeException("Unknown TypeInfo: " + columnType.getCategory());
      }
      PrimitiveObjectInspector.PrimitiveCategory type = ((PrimitiveTypeInfo) columnType).getPrimitiveCategory();
      switch (type) {
        case BOOLEAN:
          if (data instanceof BooleanWritable) {
            row.add(((BooleanWritable)data).get());
          }
          else {
            throw new TsFileSerDeException("Unexpected data type: " + data.getClass().getName() + " for Date TypeInfo: " + type);
          }
          break;
        case INT:
          if (data instanceof IntWritable) {
            row.add(((IntWritable)data).get());
          }
          else {
            throw new TsFileSerDeException("Unexpected data type: " + data.getClass().getName() + " for Date TypeInfo: " + type);
          }
          break;
        case LONG:
          if (data instanceof LongWritable) {
            row.add(((LongWritable)data).get());
          }
          else {
            throw new TsFileSerDeException("Unexpected data type: " + data.getClass().getName() + " for Date TypeInfo: " + type);
          }
          break;
        case FLOAT:
          if (data instanceof FloatWritable) {
            row.add(((FloatWritable)data).get());
          }
          else {
            throw new TsFileSerDeException("Unexpected data type: " + data.getClass().getName() + " for Date TypeInfo: " + type);
          }
          break;
        case DOUBLE:
          if (data instanceof DoubleWritable) {
            row.add(((DoubleWritable)data).get());
          }
          else {
            throw new TsFileSerDeException("Unexpected data type: " + data.getClass().getName() + " for Date TypeInfo: " + type);
          }
          break;
        case STRING:
          if (data instanceof Text) {
            row.add(data.toString());
          }
          else {
            throw new TsFileSerDeException("Unexpected data type: " + data.getClass().getName() + " for Date TypeInfo: " + type);
          }
          break;
        case TIMESTAMP:
          if (data instanceof LongWritable) {
            row.add(new Timestamp(((LongWritable)data).get()));
          }
          else {
            throw new TsFileSerDeException("Unexpected data type: " + data.getClass().getName() + " for Date TypeInfo: " + type);
          }
          break;
        default:
          throw new TsFileSerDeException("Unknown TypeInfo: " + columnType.getCategory());
      }
    }
    return row;
  }

}