<?php
  /* utf-8 charset everywhere */
  header('Content-Type: text/html; charset=utf-8');
  ini_set("default_charset", "UTF-8");
  mb_internal_encoding("UTF-8");

  /* amazon aws proxy */
  if ($_SERVER['SERVER_ADDR'] == '172.31.30.0') $_SERVER['SERVER_ADDR'] = '13.37.178.62';
  
  /* UTC timezone everywhere */
  date_default_timezone_set('UTC');
  $utc_timestamp = date('Y-m-d H:i:s');
  
  /* keep silent */
  error_reporting(E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED);
  ini_set('display_errors', 0);

  /* database connection */
  include('libraries/database.php');
  sql_connect();

  /* functions */
  include('libraries/functions.php');
  
  /* api functionality */
  include('libraries/api_request.php');

  /* single sign-on (the login pages redeem the SSO host's one-time ticket) */
  include('libraries/sso.php');

  /* support login: staff in as a tenant's support/system user via support.tracker-app.com */
  include('core/support_login.php');

  /* central database logging (additive) — GUID up front so api_request() inherits it;
     logging itself is armed later, only once a real module page is dispatched */
  include('libraries/logger.php');
  $GLOBALS['log_pageview_id'] = generate_pageview_id();

  /* output buffering */
  ob_start();
  
  /* get client */
  $client = sql("SELECT * FROM core_clients WHERE hostname = '".esc($_SERVER['HTTP_HOST'])."' LIMIT 1");
  
  /* global login */
  if (in_array($_SERVER['HTTP_HOST'], array('login.tracker-app.com','login.nubo-app.com'))) {
    $client = array('id'=>0);
  }
  
  if (!$client) die('Unknown client');
  $client_skin = sql("SELECT * FROM core_client_skins WHERE client_id = '".floor($client['id'])."' LIMIT 1");
  $client_settings = sql("SELECT * FROM core_client_settings WHERE client_id = '".floor($client['id'])."' LIMIT 1");
  
  if ($client['id'] && !$client_settings) die('Server maintenance');

  if ($client_settings['disable_autosave'] && isset($_POST['from_autosave']) && ($_POST['from_autosave'] == '1' || $_POST['from_autosave'] == 'true')) {
    /* autosave is disabled; ignore request */
    ob_end_clean(); exit;
  }
  
  $main_server = sql("SELECT * FROM core_servers WHERE id = 1 LIMIT 1");
  
  /* client timezone */
  if ($client_settings && $client_settings['timezone'] != '') {
    date_default_timezone_set($client_settings['timezone']);
    sql("SET time_zone = '".esc($client_settings['timezone'])."'");
  }
  
  /* get environment */
  $environment = sql("SELECT environment FROM global WHERE id = 1 LIMIT 1")['environment'];
  
  /* get user */
  if (isset($_COOKIE['user_id']) && isset($_COOKIE['session_id'])) {
    $check_session = sql("SELECT * FROM core_client_user_sessions WHERE client_id = '".floor($client['id'])."' AND user_id='".esc($_COOKIE['user_id'])."' AND session_id='".esc($_COOKIE['session_id'])."' AND expires > NOW() LIMIT 1");
    if ($check_session) {
      $user = sql("SELECT * FROM core_client_users WHERE id = ".floor($check_session['user_id'])." AND client_id = '".floor($client['id'])."' AND disabled = 0 LIMIT 1");
      if ($user['reseller_id']) {
        $reseller = sql("SELECT * FROM resellers WHERE reseller_id = '".esc($user['reseller_id'])."' AND client_id = '".floor($client['id'])."' LIMIT 1");
      }
      if ($user['artworker_id']) {
        $artworker = sql("SELECT * FROM logos_artworkers WHERE id = '".esc($user['artworker_id'])."' AND client_id = '".floor($client['id'])."' LIMIT 1");
      }
    } else {
      $user = false;
    }
  } else {
    $user = false;
  }

  /* user timezone */
  if ($user && $user['timezone'] != '') {
    if ($user['timezone'] == 'auto' && $_COOKIE['timezone'] != '') {
      date_default_timezone_set($_COOKIE['timezone']);
      sql("SET time_zone = '".esc($_COOKIE['timezone'])."'");
    } else {
      date_default_timezone_set($user['timezone']);
      sql("SET time_zone = '".esc($user['timezone'])."'");
    }
  }
  
  /* route request */
  $url = strtok($_SERVER["REQUEST_URI"],'?');

  /* support login: the support host's server-to-server ticket check, ahead of its ip restrictions */
  if ($url == '/login/support/verify') support_login_verify();

  /* ip restrictions */
  $path = explode('/', $url);
  if ($path[1] == 'time' && (count($path) == 2 || $path[2] == 'index')) {
    $ip_restriction = $client_settings['time_access'];
  } elseif ($path[1] == 'warehouse' || $path[1] == 'pp' || $path[1] == 'hh') {
    $ip_restriction = $client_settings['warehouse_access'];
  } else {
    $ip_restriction = $client_settings['tracker_access'];
  }
  $allowed_ips = array_filter(explode(',', $ip_restriction));
  
  if (count($allowed_ips)) {
    if (!in_array($_SERVER['REMOTE_ADDR'], $allowed_ips)) {
      $remote_server = sql("SELECT * FROM core_servers WHERE id = 1 LIMIT 1");
      
      $access = sql_remote($remote_server['ip'],"SELECT * FROM tracker_access WHERE ip = '".esc($_SERVER['REMOTE_ADDR'])."' LIMIT 1");
      if (!$access) {
        die('Access denied for '.$_SERVER['REMOTE_ADDR']);
      }
    }
  }

  /* support login (/login/support, /hh/login/support, /pp/login/support and the handoff) */
  support_login_route($url);

  /* productionscheduler timezones */
  if (explode('/', $_SERVER["REQUEST_URI"])[1] == 'productionscheduler' && isset($_REQUEST['location_group_id'])) {
    $override_tz = sql("SELECT timezone FROM inventory_location_groups WHERE client_id = ".floor($client['id'])." AND location_group_id = '".esc($_REQUEST['location_group_id'])."' LIMIT 1");
    if ($override_tz && $override_tz['timezone']) {
      date_default_timezone_set($override_tz['timezone']);
      sql("SET time_zone = '".esc($override_tz['timezone'])."'");
    }
  }

  /* custom header color for Hari */
  if ($client['client_slug'] == 'antigua' && $user['id'] == 1636) $client_skin['header_background'] = '101010';
  
  /* restrict warehouse pin-logins to warehouse module */
  if ($user['username'] != 'system') {
    switch ($check_session['restriction']) {
      case 'warehouse':
        if (!in_array($path[1], array('warehouse','dispatch','login-warehouse','logout-warehouse','select-warehouse'))) $user = false;
      break;
      case 'pp':
        if ($path[1] != 'pp') { header('Location: /pp'); exit; }
      break;
      case 'hh':
        if ($path[1] != 'hh') { header('Location: /hh'); exit; }
      break;
      case '':
        if ($path[1] == 'pp') $user = false;
        if ($path[1] == 'hh') $user = false;
      break;
    }
  }
  
  /* time tracker module */
  if ($url == '/time') {
    $user = array('id'=>0, 'admin'=>false);
  }

  if (!$client['id']) {
    /* global login/signup */
    if (in_array($_SERVER['HTTP_HOST'], array('login.tracker-app.com','login.nubo-app.com'))) {
      include('core/global_login.php');
    } elseif (in_array($_SERVER['HTTP_HOST'], array('signup.nubo-app.com'))) {
      include('core/global_signup.php');
    }
  } elseif (!$user) {
    /* not logged in */
    switch ($url) {
      case ($path[1] == 'pp'):
        /* get modules for client */
        $client_has_module = sql("
          SELECT core_modules.*, core_client_modules.enable_pages, core_client_modules.disable_pages, core_user_modules.* FROM core_modules
          LEFT JOIN core_client_modules ON core_client_modules.module_id = core_modules.id
          LEFT JOIN core_user_modules ON core_user_modules.module_id = core_modules.id
          WHERE core_client_modules.client_id = ".floor($client['id'])." AND core_modules.slug = '".esc($path[1])."'
          LIMIT 1
        ");
        
        if ($client_has_module) {
          include('core/module_pp.php');
        } else {
          die('Access denied');
        }
      break;
      case ($path[1] == 'hh'):
        /* get modules for client */
        $client_has_module = sql("
          SELECT core_modules.*, core_client_modules.enable_pages, core_client_modules.disable_pages, core_user_modules.* FROM core_modules
          LEFT JOIN core_client_modules ON core_client_modules.module_id = core_modules.id
          LEFT JOIN core_user_modules ON core_user_modules.module_id = core_modules.id
          WHERE core_client_modules.client_id = ".floor($client['id'])." AND core_modules.slug = '".esc($path[1])."'
          LIMIT 1
        ");
        
        if ($client_has_module) {
          include('core/module_hh.php');
        } else {
          die('Access denied');
        }
      break;
      case '/login':
        include('core/login.php');
      break;
      case '/login-warehouse':
      case '/login-warehouse/login':
        include('core/login-warehouse.php');
      break;
      case '/select-warehouse':
        include('core/select-warehouse.php');
      break;
      case '/passwordreset':
        include('core/passwordreset.php');
      break;
      case (substr($url, 0, 15) == '/forgotpassword'):
        include('core/forgotpassword.php');
      break;
      case (substr($url, 0, 10) == '/warehouse'):
        header('Location: /login-warehouse');
      break;
      case '/logout-warehouse':
        header('Location: /login-warehouse');
      break;
      default:
        $page = substr($_SERVER['REQUEST_URI'],1);
        if ($page && $page != 'logout') {
          header('Location: /login?redirect='.$page);
        } else {
          header('Location: /login');
        }
      break;
    }
  } else {
    if ($user['username'] == 'system' && $_SERVER['REQUEST_URI'] == '/sandbox/1') {
      mysqli_query($GLOBALS['sql_link'], "UPDATE core_client_user_sessions SET sandbox = '[]' WHERE session_id = '".esc($check_session['session_id'])."' LIMIT 1");
      header('Location: /');
      exit;
    }

    if ($user['username'] == 'system' && $_SERVER['REQUEST_URI'] == '/sandbox/0') {
      mysqli_query($GLOBALS['sql_link'], "UPDATE core_client_user_sessions SET sandbox = '' WHERE session_id = '".esc($check_session['session_id'])."' LIMIT 1");
      header('Location: /');
      exit;
    }
    
    /* admin access */
    if ($user['admin']) {
      $admin_module = 'OR core_modules.id = 9';
    } else {
      $admin_module = '';
    }
    
    if ($user['system_power_user']) {
      $admin_module .= ' OR core_modules.id = 83'; /* development tools [devtools] module */
    }
    
//    if ($client['id'] == 1) { $admin_module .= ' OR core_modules.id = 40'; }
    
    /* get modules for client */
    $client_modules = sql("
      SELECT core_modules.*, core_client_modules.enable_pages, core_client_modules.disable_pages, core_user_modules.* FROM core_modules
      LEFT JOIN core_client_modules ON core_client_modules.module_id = core_modules.id
      LEFT JOIN core_user_modules ON core_user_modules.module_id = core_modules.id
      WHERE (core_client_modules.client_id = ".floor($client['id'])." AND core_user_modules.user_id = ".floor($user['id']).") $admin_module
      ORDER BY FIND_IN_SET(core_modules.id, '9,8,40'), core_client_modules.display_order, core_modules.id
    ");
    
    /* user module */
    $client_modules[] = array('id'=>9999,'name'=>htmlentities($user['full_name']), 'slug'=>'user', 'default_path'=>'', 'menu_items'=>'{"profile":"Profile","module-menu":"Module Menu","tasks":"Tasks","support":"Support Request","tickets/support":"Support Tickets","development":"Development Request","tickets/development":"Development Tickets"}');

    /* time tracker */
    if ($user['id'] == 0) {
      $client_modules[] = array('id'=>46,'name'=>'Time Tracker', 'slug'=>'time', 'default_path'=>'index', 'menu_items'=>'{}');
    }
    
    /* array-list of modules a client has */
    $client_has_module = array();
    if ($client_modules) foreach($client_modules as $client_module) {
      $client_has_module[$client_module['slug']] = $client_module['id'];
    }
    
    /* get page tabs settings */
    $page_tabs_orders = sql("SELECT tabs_interface_clients.*, tabs_interface.default_tab_name, tabs_interface.is_standard, tabs_interface.tab_class
                             FROM tabs_interface_clients
                             LEFT JOIN tabs_interface
                             ON tabs_interface_clients.interface_tab_id = tabs_interface.tab_id
                             WHERE tabs_interface_clients.client_id = ".floor($client['id'])."
                             ORDER BY tabs_interface_clients.display_order
                            ");

    /* module routing */
    switch ($url) {
      case '/logout':
        include('core/logout.php');
      break;
      case '/logout-warehouse':
        include('core/logout-warehouse.php');
      break;
      case '/login-warehouse':
      case '/login-warehouse/login':
        header('Location: /warehouse');
      break;
      case '/select-warehouse':
        include('core/select-warehouse.php');
      break;
      case '/':
      case '/login':
      case '/passwordreset':
        foreach ($client_modules as $match) {
          if ($match['is_default']) { if ($match['default_path']) { header('Location: /'.$match['slug'].'/'.$match['default_path']); exit; } else { header('Location: /'.$match['slug']); exit; } }
        }

        $match = $client_modules[0];
        if ($match['default_path']) { header('Location: /'.$match['slug'].'/'.$match['default_path']); exit; } else { header('Location: /'.$match['slug']); exit; }
      break;
      default:
        $path = explode('/', $url);
        foreach ($client_modules as $match) {
          if ($match['slug'] == $path[1]) {
            $module = $match;
            
            if (file_exists('modules/'.$path[1].'/functions.php')) include('modules/'.$path[1].'/functions.php');
            
            $endpoint = $path;
            /* dispatch */
            if ($endpoint[1] == 'warehouse' && $endpoint[2] == 'dispatch') { $endpoint = array('system','dispatch',$endpoint[3]); }
            if ($endpoint[1] == 'warehouse' && $endpoint[2] == 'dispatchquick') { $endpoint = array('system','dispatch',$endpoint[3]); }
            if ($endpoint[1] == 'warehouse' && $endpoint[2] == 'dispatch-quick-tdi') { $endpoint = array('system','dispatch',$endpoint[3]); }
            if ($endpoint[1] == 'dispatch' && $endpoint[2] == 'dispatches' && $endpoint[3] == 'set') { $endpoint = array('system','dispatch',$endpoint[4]); }
            
            /* transfer receiver */
            if ($endpoint[1] == 'warehouse' && $endpoint[2] == 'transfer' && $endpoint[3] == 'putaway' && $endpoint[4] == 'receive') { $endpoint = array('system','transfer',$endpoint[5]); }
            if ($endpoint[1] == 'inventory' && $endpoint[2] == 'transfers' && $endpoint[3] == 'receipt') { $endpoint = array('system','transfer',$endpoint[4]); }
            if ($endpoint[1] == 'hh' && $endpoint[2] == 'transfer' && $endpoint[3] == 'receipt') { $endpoint = array('system','transfer',$endpoint[4]); }
            
            $endpoint = join('/',array_filter($endpoint));

            if ($_POST['track_pageview']) {
              sql("UPDATE core_client_user_history SET last_open = NOW() WHERE pageview_id = ".floor($_POST['track_pageview'])." AND user_id = '".floor($user['id'])."' AND client_id = '".floor($client['id'])."' AND session_id = '".esc($_COOKIE['session_id'])."' AND endpoint = '/".esc($endpoint)."'");
              ob_end_clean();
              if (file_exists('modules/'.$path[1].'/track_pageview.php')) include('modules/'.$path[1].'/track_pageview.php');
              exit;
            }

            $GLOBALS['pageview_id'] = sql("INSERT INTO core_client_user_history SET user_id = '".floor($user['id'])."', client_id = '".floor($client['id'])."', session_id = '".esc($_COOKIE['session_id'])."', endpoint = '/".esc($endpoint)."', first_open = NOW(), last_open = NOW()");

            $postlog = substr($utc_timestamp,0,4).substr($utc_timestamp,5,2).substr($utc_timestamp,8,2).'-'.substr($utc_timestamp,11,2);
            file_put_contents('logs/postlog-'.$postlog.'.log', $utc_timestamp.' '.$user['id'].'@'.$client['id'].' '.log_username().' '.$GLOBALS['pageview_id'].' '.$_SERVER['REQUEST_URI'].' '.$_SERVER['REQUEST_METHOD'].' '.json_encode($_REQUEST)."\n", FILE_APPEND);
            @chmod(dirname(__FILE__).'/logs/postlog-'.$postlog.'.log', 0666);

            log_init('page'); // arm central DB logging — same chokepoint as the file postlog (real module pages only)

            $concurrent = sql("SELECT user_id FROM core_client_user_history WHERE client_id = '".floor($client['id'])."' AND session_id != '".esc($_COOKIE['session_id'])."' AND endpoint = '/".esc($endpoint)."' AND last_open > DATE_SUB(NOW(), INTERVAL 10 SECOND) LIMIT 1");
            if ($concurrent) {
              $GLOBALS['concurrent_user'] = $concurrent['user_id'];
              $GLOBALS['concurrent_full_name'] = sql("SELECT full_name FROM core_client_users WHERE client_id = ".$client['id']." AND id = '".esc($GLOBALS['concurrent_user'])."' LIMIT 1")['full_name'];
            } else {
              $GLOBALS['concurrent_user'] = false;
              $GLOBALS['concurrent_full_name'] = false;
            }
            
            if ($module['slug'] == 'time' && (count($path) == 2 || $path[2] == 'index')) {
              include('core/module_mobile.php');
            } elseif ($module['slug'] == 'warehouse') {
              include('core/module_mobile.php');
            } elseif ($module['slug'] == 'pp') {
              include('core/module_pp.php');
            } elseif ($module['slug'] == 'hh') {
              include('core/module_hh.php');
            } else {
              include('core/module_page.php');
            }
            
            /* some extra memory for translation logics */
            ini_set('memory_limit', '8G');

            $replacements = explode("\n", ob_get_clean());
            foreach ($replacements as $replacement) {
              switch ($client_settings['locale']) {
                case 'en-gb':
                  $replacement = str_replace(array('{Color}','{Colors}'),array('Colour','Colours'),$replacement);
                  $replacement = str_replace(array('{color_lowercase}','{colors_lowercase}'),array('colour','colours'),$replacement);
                break;
                case 'en-us':
                  $replacement = str_replace(array('{Color}','{Colors}'),array('Color','Colors'),$replacement);
                  $replacement = str_replace(array('{color_lowercase}','{colors_lowercase}'),array('color','colors'),$replacement);
                break;
              }
              echo $replacement."\n";
            }

            exit;
          }
        }
        die('Access denied');
      break;
    }
  }
