import $ from "jquery";
import * as JSX from "./jsx";

export interface FtpEntry {
  name: string;
  date: string;
  time: string;
  size: string;
  isdir: boolean;
}

export function ftpEntryFromLine( line: string ): FtpEntry | null {
  const isdir = line[line.length - 1] == '-';
  const name = line.slice( 0, line.indexOf( " " ) );
  if( name == ".." ) return null;
  if( !name )
    return null;
  let date = '';
  let time = '';
  let size = ''

  if( !isdir ) {
    let end = line.lastIndexOf( " " );
    size = line.slice( end + 1 );
    date = line.slice( line.indexOf( " " ) + 1, end );
    end = date.indexOf( " " );
    const datetime = date.slice( date.search( /[0-9]/ ) );
    end = datetime.indexOf( ' ' );
    date = datetime.slice( 0, end );
    time = datetime.slice( end + 1 );
    time = time.slice( 0, time.indexOf( " " ) );
  } else {
    let start = line.search( /[0-9]/ )
    date = line.slice( start );
    let end = date.indexOf( " " );
    date = date.slice( 0, end );

    time = line.slice( start + end + 1, line.length - 1 );
    time = time.slice( 0, time.indexOf( " " ) );
  }

  const day = date.slice( 0, date.indexOf( "-" ) );
  const month = date.slice( date.indexOf( "-" ) + 1, date.indexOf( "-" ) + 4 );
  const year = date.slice( -2 );

  date = `${year}/${monthToNumber( month )}/${day}`;

  return { name, date, time, size, isdir };
}

export async function ftpGetEntries( endpoint: string, showBack: boolean = false ): Promise<FtpEntry[]> {
  const packages = await fetch( "https://networkheaven.net/" + endpoint );
  const text = await packages.text();

  const pkgBody = $( <div /> );
  pkgBody.html( text );
  pkgBody.html( pkgBody.find( "body" ).html() );
  const pre = pkgBody.find( "pre" )[0].innerText;

  const ret = [];
  if( showBack ) {
     ret.push({
      name: '../',
      date: ' ',
      time: ' ',
      size: '',
      isdir: true
    } );
  }

  const lines = pre.split( "\n" );
  for( const line of lines ) {
    if( !line.length )
      continue;

    const entry = ftpEntryFromLine( line );
    if( entry )
      ret.push( entry );
  }

  return ret;
}


export function escapeHtml( html: string ) {
  const entityMap = {
    '&': '&amp;',
    '<': '&lt;',
    '>': '&gt;',
    '"': '&quot;',
    "'": '&#39;',
    '/': '&#x2F;',
    '`': '&#x60;',
    '=': '&#x3D;'
  };

  return String( html ).replace( /[&<>"'`=\/]/g, ( s ) => {
    return entityMap[s];
  } );
}

export function parseJWT( token: string ) : any {
  const parts = token.split( '.' );
  let encoded = parts[1];
  encoded = encoded.replace(/-/g, '+').replace(/_/g, '/');
  const pad = encoded.length % 4;
  if( pad === 1 )
    throw new Error( 'what the fuck' );
  if( pad > 1 )
    encoded += new Array( 5 - pad ).join( '=' );

  const payload = JSON.parse( atob( encoded ) );
  return payload;
}

export function sizeHumanReadable( size: number, short: boolean = false ) {
  if( size < 1024 )
    return size + (short? 'B' : ' B');
  else if( size < 1024 * 1024 )
    return ( size / 1024 ).toFixed( short? 1: 2 ) + (short? 'K' : ' KB');
  else if( size < 1024 * 1024 * 1024 )
    return ( size / 1024 / 1024 ).toFixed( short? 1 : 2 ) + (short? 'M' : ' MB');
  else
    return ( size / 1024 / 1024 / 1024 ).toFixed( short? 1 : 2 ) + (short? 'G':' GB');
}

export function monthToNumber( month: string ) {
  const months = [
    '',
    'jan',
    'feb',
    'mar',
    'apr',
    'may',
    'jun',
    'jul',
    'aug',
    'sep',
    'oct',
    'nov',
    'dec'
  ];
  return months.indexOf( month.toLowerCase() );
};
