<?php
namespace admin\factory;

class Update
{
  public static function update()
  {
    global $mdb, $settings;

    \S::delete_session( 'new-version' );

    $versions = file_get_contents( 'http://www.cmspro.project-dc.pl/updates/versions.php?key=' . $settings['update_key'] );
    $versions = explode( PHP_EOL, $versions );

    foreach ( $versions as $ver )
    {
      $ver = trim( $ver );
      if ( (float)$ver > (float)\S::get_version() )
      {
        if ( strlen( $ver ) == 5 )
          $dir = substr( $ver, 0, strlen( $ver ) - 2 ) . 0;
        else
          $dir = substr( $ver, 0, strlen( $ver ) - 1 ) . 0;

        $baseUrl = 'http://www.cmspro.project-dc.pl/updates/' . $dir;

        /* pobranie paczki ZIP */
        $file = file_get_contents( $baseUrl . '/ver_' . $ver . '.zip' );

        $dlHandler = fopen( 'update.zip' , 'w' );
        if ( !fwrite( $dlHandler, $file ) )
          return false;
        fclose( $dlHandler );

        if ( !file_exists( 'update.zip' ) )
          return false;

        /* pobranie manifestu JSON (nowy system) lub fallback na legacy _sql.txt / _files.txt */
        $manifest = null;
        $manifestJson = @file_get_contents( $baseUrl . '/ver_' . $ver . '_manifest.json' );
        if ( $manifestJson )
        {
          if ( substr( $manifestJson, 0, 3 ) === "\xEF\xBB\xBF" )
            $manifestJson = substr( $manifestJson, 3 );
          $manifest = @json_decode( $manifestJson, true );
        }

        if ( is_array( $manifest ) )
        {
          /* weryfikacja checksum SHA256 */
          if ( !empty( $manifest['checksum_zip'] ) )
          {
            $expectedHash = str_replace( 'sha256:', '', $manifest['checksum_zip'] );
            $actualHash = hash_file( 'sha256', 'update.zip' );
            if ( $expectedHash !== $actualHash )
            {
              unlink( 'update.zip' );
              return false;
            }
          }

          /* aktualizacja bazy danych z manifestu */
          if ( !empty( $manifest['sql'] ) && is_array( $manifest['sql'] ) )
          {
            foreach ( $manifest['sql'] as $query )
            {
              $query = trim( $query );
              if ( $query )
                $mdb -> query( $query );
            }
          }

          /* usuwanie plikow z manifestu */
          if ( !empty( $manifest['files']['deleted'] ) && is_array( $manifest['files']['deleted'] ) )
          {
            foreach ( $manifest['files']['deleted'] as $filePath )
            {
              $fullPath = '../' . $filePath;
              if ( file_exists( $fullPath ) )
                unlink( $fullPath );
            }
          }

          /* usuwanie katalogow z manifestu */
          if ( !empty( $manifest['directories_deleted'] ) && is_array( $manifest['directories_deleted'] ) )
          {
            foreach ( $manifest['directories_deleted'] as $dirPath )
            {
              $fullPath = '../' . $dirPath;
              if ( is_dir( $fullPath ) )
                \S::delete_dir( $fullPath );
            }
          }
        }
        else
        {
          /* legacy: aktualizacja bazy danych z _sql.txt */
          $sql = @file_get_contents( $baseUrl . '/ver_' . $ver . '_sql.txt' );
          if ( $sql )
          {
            $sql = explode( PHP_EOL, $sql );
            if ( is_array( $sql ) ) foreach ( $sql as $query )
            {
              $query = trim( $query );
              if ( $query )
                $mdb -> query( $query );
            }
          }

          /* legacy: usuwanie zbednych plikow z _files.txt */
          $lines = @file_get_contents( $baseUrl . '/ver_' . $ver . '_files.txt' );
          if ( $lines )
          {
            $lines = explode( PHP_EOL, $lines );
            if ( is_array( $lines ) ) foreach ( $lines as $line )
            {
              if ( strpos( $line, 'F: ' ) !== false )
              {
                $delFile = substr( $line, 3, strlen( $line ) );
                if ( file_exists( $delFile ) )
                  unlink( $delFile );
              }

              if ( strpos( $line, 'D: ' ) !== false )
              {
                $delDir = substr( $line, 3, strlen( $line ) );
                if ( is_dir( $delDir ) )
                  \S::delete_dir( $delDir );
              }
            }
          }
        }

        /* wgrywanie nowych plikow */
        $file_name = 'update.zip';

        $path = pathinfo( realpath( $file_name ), PATHINFO_DIRNAME );
        $path = substr( $path, 0, strlen( $path ) - 5 );
        $zip = new \ZipArchive;
        $res = $zip -> open( $file_name );
        if ( $res === TRUE )
        {
          $zip -> extractTo( $path );
          $zip -> close();
          unlink( $file_name );
        }

        $updateThis = fopen( '../libraries/version.ini', 'w' );
        fwrite( $updateThis, $ver );
        fclose( $updateThis );

        return true;
      }
    }
  }
}
