#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>

typedef enum PROTOCOL_STATUS {
  PS_NONE,
  PS_SNIFF,
  PS_HTTP_READ_HEADER,
  PS_HTTP_READ_BODY,
  PS_STREAM,
  PS_ERROR

} PROTOCOL_STATUS;

typedef enum PROTOCOL_NAME {
  PN_NONE,
  PN_HTTP,
  PN_HTTP_CHUNKED,
  PN_HTTP_WEBSOCKET,
  PN_HTTP_KEEP_ALIVE,
  PN_HTTP_REQUEST,
  PN_SSH,
  PN_RAW,
  PN_ERROR
} PROTOCOL_NAME ;

char * http_get_header_value(char * headers, char * key){
  char * result = NULL;
  char * start = strstr(headers, key);
  if(!start){
    return NULL;
  }
  start += strlen(key);
  start += 2;
  char * end = strstr(start, "\r\n");
  if(!end){
    return NULL;
  }
  result = (char *)malloc(end - start + 1);
  strncpy(result, start, end - start);
  result[end-start] = 0;
  return result;
}

PROTOCOL_NAME protocol_sniff(int fd){
  char buffer[4096] = {0};

  ssize_t bytes_received = recv(fd, buffer,sizeof(buffer),MSG_PEEK);
  buffer[bytes_received] = 0;
  if(bytes_received <= 0){
    return PN_ERROR;
  }

  if(strncmp(buffer,"HTTP",4) == 0){
    if(strstr(buffer,"Transfer-Encoding: chunked"))
      return PN_HTTP_CHUNKED;
    if(strstr(buffer,"Connection: keep-alive")){
      return PN_HTTP_KEEP_ALIVE;
    }
    return PN_HTTP;
  }
  if(!strncmp(buffer,"GET ",4) && strstr(buffer,"Upgrade: websocket")){
    return PN_HTTP_WEBSOCKET;
  }
  if(!strncmp(buffer,"SSH ",4)){
    return PN_SSH;
  }
  if(!strncmp(buffer,"GET ", 4)){
    return PN_HTTP_REQUEST;
  }
  return PN_RAW;
}