<?php
  $allowed_domains = array(
    'companyapp.net',
    'companyapp.co.uk',
    'localhost'
  );
  $referer = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '';
  $parsed_url = parse_url($referer);
  $referer_host = isset($parsed_url['host']) ? $parsed_url['host'] : '';

  // URL
  $url = reconstruct_url($_SERVER['DOCUMENT_ROOT'] . $_SERVER['REQUEST_URI']);

  // Allow files from advanced slides
  $ref_pattern = '/^https:\/\/[a-z0-9-]+\.companyapp\.(net|co\.uk)\/.*\/slides\/[a-zA-Z0-9]+\/[a-zA-Z0-9]+\.html$/i';
  $ref_matched = preg_match($ref_pattern, $referer);

  $debug = true;

  $user_agent = $_SERVER['HTTP_USER_AGENT'];

  // When using a proxy, the URL has to be replaced with the correct path
  $pattern_dev = '/^\/var\/www\/dev-app\/build\/cms-radisson(.*)$/';
  $replacement_dev = '/var/www/dev-files.companyapp.net/dev-cms-radisson';

  $pattern_staging = '/^\/home\/stge_radisson\/radisson\/build\/cms-radisson(.*)$/';
  $replacement_staging = '/srv/staging/assets/radisson/staging-cms-radisson$1';

  $pattern_prod = '/^\/home\/prod_radisson\/radisson\/build\/cms-radisson(.*)$/';
  $replacement_prod = '/srv/production/assets/radisson/cms-radisson$1';

  $file = preg_replace($pattern_dev, $replacement_dev, $url);
  $file = preg_replace($pattern_staging, $replacement_staging, $url);
  $file = preg_replace($pattern_prod, $replacement_prod, $url);
  $file = urldecode($file);

  if ($debug) {
    handle_file($url, $file);
  } else {
    // Allow everything for outlook addin
    if (strpos($url, '/cms-radisson/addin/') !== false) {
      handle_file($url, $file);
    } else {
      if (($referer_host && (in_array($referer_host, $allowed_domains) || preg_match('/\.companyapp\.(net|co\.uk)$/', $referer_host))) || in_array($_SERVER['SERVER_NAME'], $allowed_domains) || $ref_matched) {
        handle_file($url, $file);
      } else {
        header('HTTP/1.1 403 Forbidden');
        echo 'Access denied';
        exit;
      }
    }
  }

  function handle_file($url, $file){
    if (strpos($url, 'presentation_book.php') !== false) {
      $url_parts = parse_url($url);
      include($url_parts['path']); // Execute the PHP file
      exit;
    } else if (strpos($url, '/cms-radisson/addin/') !== false) {
      $url_parts = parse_url($url);

      if (file_exists($url_parts['path'])) {
        serve_file($url_parts['path']);
      } else {
        header('HTTP/1.1 404 Not Found');
        echo 'File not found: ' . $file . ' - URL: ' . $url_parts['path'];
        exit;
      }
    } else {
      if (file_exists($file)) {
        header('Content-Type: ' . mime_type($file));
        serve_file($file);
      } else {
        header('HTTP/1.1 404 Not Found');
        echo 'File not found: ' . $file . ' - URL: ' . $url;
        exit;
      }
    }
  }

  function serve_file($filepath) {
    $browser = get_the_browser();
    if ($browser === 'Safari') {
      // Safari uses Range header 
      // On Chrome 416 is thrown because of the way chrome sends the requests
      // Safari is an exception
      if (isset($_SERVER['HTTP_RANGE'])) {
        $file_size = filesize($filepath);
        $ranges = parse_range_header($file_size);
        if (count($ranges) === 1) {
            $range = $ranges[0];
            header('HTTP/1.1 206 Partial Content');
            header('Content-Length: ' . ($range['end'] - $range['start'] + 1));
            header('Content-Range: bytes ' . $range['start'] . '-' . $range['end'] . '/' . $file_size);
            readfile_chunked($filepath, $range['start'], $range['end']);
        } else {
          header('HTTP/1.1 416 Range Not Satisfiable');
          header('Content-Range: */' . $file_size);
        }
      } else {
        return_file($filepath);
      }
    } else {
      return_file($filepath);
    }
  }

  function return_file($filepath) {
    header('Content-Type: ' . mime_type($filepath));
    readfile($filepath);
  }

  function parse_range_header($file_size) {
    $range_header = $_SERVER['HTTP_RANGE'];
    $range = substr($range_header, strpos($range_header, '=') + 1);
    $ranges = explode(',', $range);
    $result = [];
    foreach ($ranges as $range) {
      $parts = explode('-', $range);
      $start = intval($parts[0]);
      $end = isset($parts[1]) ? intval($parts[1]) : $file_size - 1;
      if ($start < $file_size && $end < $file_size && $start <= $end) {
        $result[] = ['start' => $start, 'end' => $end];
      }
    }
    return $result;
  }

  function readfile_chunked($file, $start, $end) {
    $chunk_size = 8192; // You can adjust this value as needed
    $handle = fopen($file, 'rb');
    fseek($handle, $start);

    while (!feof($handle) && $start <= $end) {
      $bytes_to_read = min($chunk_size, $end - $start + 1);
      $data = fread($handle, $bytes_to_read);
      echo $data;
      flush();
      $start += $bytes_to_read;
    }
    fclose($handle);
  }

  function reconstruct_url($url) {
    $url_parts = parse_url($url);
    return $url_parts['path'];
  }

  function mime_type($filename) {
    $mime_types = array(
      'txt' => 'text/plain',
      'htm' => 'text/html',
      'html' => 'text/html',
      'css' => 'text/css',
      'json' => array(
        'application/json',
        'text/json'
      ),
      'xml' => 'application/xml',
      'swf' => 'application/x-shockwave-flash',
      'flv' => 'video/x-flv',
      
      'hqx' => 'application/mac-binhex40',
      'cpt' => 'application/mac-compactpro',
      'csv' => array(
        'text/x-comma-separated-values',
        'text/comma-separated-values',
        'application/octet-stream',
        'application/vnd.ms-excel',
        'application/x-csv',
        'text/x-csv',
        'text/csv',
        'application/csv',
        'application/excel',
        'application/vnd.msexcel'
      ),
      'bin' => 'application/macbinary',
      'dms' => 'application/octet-stream',
      'lha' => 'application/octet-stream',
      'lzh' => 'application/octet-stream',
      'exe' => array(
        'application/octet-stream',
        'application/x-msdownload'
      ),
      'class' => 'application/octet-stream',
      'so' => 'application/octet-stream',
      'sea' => 'application/octet-stream',
      'dll' => 'application/octet-stream',
      'oda' => 'application/oda',
      'ps' => 'application/postscript',
      'smi' => 'application/smil',
      'smil' => 'application/smil',
      'mif' => 'application/vnd.mif',
      'wbxml' => 'application/wbxml',
      'wmlc' => 'application/wmlc',
      'dcr' => 'application/x-director',
      'dir' => 'application/x-director',
      'dxr' => 'application/x-director',
      'dvi' => 'application/x-dvi',
      'gtar' => 'application/x-gtar',
      'gz' => 'application/x-gzip',
      'php' => 'application/x-httpd-php',
      'php4' => 'application/x-httpd-php',
      'php3' => 'application/x-httpd-php',
      'phtml' => 'application/x-httpd-php',
      'phps' => 'application/x-httpd-php-source',
      'js' => array(
        'application/javascript',
        'application/x-javascript'
      ),
      'sit' => 'application/x-stuffit',
      'tar' => 'application/x-tar',
      'tgz' => array(
        'application/x-tar',
        'application/x-gzip-compressed'
      ),
      'xhtml' => 'application/xhtml+xml',
      'xht' => 'application/xhtml+xml',
      'bmp' => array(
        'image/bmp',
        'image/x-windows-bmp'
      ),
      'gif' => 'image/gif',
      'jpeg' => array(
        'image/jpeg',
        'image/pjpeg'
      ),
      'jpg' => array(
        'image/jpeg',
        'image/pjpeg'
      ),
      'jpe' => array(
        'image/jpeg',
        'image/pjpeg'
      ),
      'png' => array(
        'image/png',
        'image/x-png'
      ),
      'tiff' => 'image/tiff',
      'tif' => 'image/tiff',
      'shtml' => 'text/html',
      'text' => 'text/plain',
      'log' => array(
        'text/plain',
        'text/x-log'
      ),
      'rtx' => 'text/richtext',
      'rtf' => 'text/rtf',
      'xsl' => 'text/xml',
      'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
      'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
      'word' => array(
        'application/msword',
        'application/octet-stream'
      ),
      'xl' => 'application/excel',
      'eml' => 'message/rfc822',
      
      // images
      'png' => 'image/png',
      'jpe' => 'image/jpeg',
      'jpeg' => 'image/jpeg',
      'jpg' => 'image/jpeg',
      'gif' => 'image/gif',
      'bmp' => 'image/bmp',
      'ico' => 'image/vnd.microsoft.icon',
      'tiff' => 'image/tiff',
      'tif' => 'image/tiff',
      'svg' => 'image/svg+xml',
      'svgz' => 'image/svg+xml',
      
      // archives
      'zip' => array(
        'application/x-zip',
        'application/zip',
        'application/x-zip-compressed'
      ),
      'rar' => 'application/x-rar-compressed',
      'msi' => 'application/x-msdownload',
      'cab' => 'application/vnd.ms-cab-compressed',
      
      // audio/video
      'mid' => 'audio/midi',
      'midi' => 'audio/midi',
      'mpga' => 'audio/mpeg',
      'mp2' => 'audio/mpeg',
      'mp3' => array(
        'audio/mpeg',
        'audio/mpg',
        'audio/mpeg3',
        'audio/mp3'
      ),
      'aif' => 'audio/x-aiff',
      'aiff' => 'audio/x-aiff',
      'aifc' => 'audio/x-aiff',
      'ram' => 'audio/x-pn-realaudio',
      'rm' => 'audio/x-pn-realaudio',
      'rpm' => 'audio/x-pn-realaudio-plugin',
      'ra' => 'audio/x-realaudio',
      'rv' => 'video/vnd.rn-realvideo',
      'wav' => array(
        'audio/x-wav',
        'audio/wave',
        'audio/wav'
      ),
      'mpeg' => 'video/mpeg',
      'mpg' => 'video/mpeg',
      'mpe' => 'video/mpeg',
      'qt' => 'video/quicktime',
      'mov' => 'video/quicktime',
      'avi' => 'video/x-msvideo',
      'movie' => 'video/x-sgi-movie',
      
      // adobe
      'pdf' => 'application/pdf',
      'psd' => array(
        'image/vnd.adobe.photoshop',
        'application/x-photoshop'
      ),
      'ai' => 'application/postscript',
      'eps' => 'application/postscript',
      'ps' => 'application/postscript',
      
      // ms office
      'doc' => 'application/msword',
      'rtf' => 'application/rtf',
      'xls' => array(
        'application/excel',
        'application/vnd.ms-excel',
        'application/msexcel'
      ),
      'ppt' => array(
        'application/powerpoint',
        'application/vnd.ms-powerpoint'
      ),
      
      // open office
      'odt' => 'application/vnd.oasis.opendocument.text',
      'ods' => 'application/vnd.oasis.opendocument.spreadsheet'
    );
    
    $ext = explode('.', $filename);
    $ext = strtolower(end($ext));
    
    if (array_key_exists($ext, $mime_types)) {
      return (is_array($mime_types[$ext])) ? $mime_types[$ext][0] : $mime_types[$ext];
    } else if (function_exists('finfo_open')) {
      if (file_exists($filename)) {
        $finfo    = finfo_open(FILEINFO_MIME);
        $mimetype = finfo_file($finfo, $filename);
        finfo_close($finfo);
        return $mimetype;
      }
    }
    
    return 'application/octet-stream';
  }

  function get_the_browser() {
    if(strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE') !== false)
      return 'Internet explorer';
    elseif(strpos($_SERVER['HTTP_USER_AGENT'], 'Trident') !== false)
        return 'Internet explorer';
    elseif(strpos($_SERVER['HTTP_USER_AGENT'], 'Firefox') !== false)
      return 'Mozilla Firefox';
    elseif(strpos($_SERVER['HTTP_USER_AGENT'], 'Chrome') !== false)
      return 'Google Chrome';
    elseif(strpos($_SERVER['HTTP_USER_AGENT'], 'Opera Mini') !== false)
      return "Opera Mini";
    elseif(strpos($_SERVER['HTTP_USER_AGENT'], 'Opera') !== false)
      return "Opera";
    elseif(strpos($_SERVER['HTTP_USER_AGENT'], 'Safari') !== false)
      return "Safari";
    else
      return 'Other';
  }
?>