<?php
if( !defined( 'MEDIAWIKI' )) die( -1 ); # guard against stray browsers


final class MailishUsername
{


    # Canonicalizes an email address.  Returns the canonical form.
    #
    static function canonicalEmail( $email )
    {
        # cf. votorola.g.mail.InternetAddressX.canonicalize()

        $a = strpos( $email, '@' );
        if( !$a ) return $email; # won't actually occur, assuming isValidEmailAddr

        return substr($email,0,$a) . '@' . strtolower(substr($email,$a+1));
    }



    # Translates a canonical email address to a username.  Returns the username.
    #
    static function emailToUsername( $email )
    {
        # cf. http://reluk.ca/project/votorola/_/javadoc/votorola/a/voter/IDPair.html#appendUsername(java.lang.String,%20java.lang.StringBuilder)
        $u = ''; # so far
        $cN = strlen( $email );

       # First character
       # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        $c = 0;
        {
            $ch = substr( $email, $c++, 1 );
            $chUp = strtoupper( $ch );
            $u .= $chUp;
            if( $ch == $chUp ) $atSurrogateChar = ' ';
            else $atSurrogateChar = '-';
        }

       # Remainder of local part and at-surrogate
       # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        for( ;; )
        {
            if( $c >= $cN ) return $u; # error, no '@'
            $ch = substr( $email, $c++, 1 );
            if( $ch == '@' ) break;
            elseif( $ch == '_' ) $ch = ' '; # normalize
            $u .= $ch;
        }
        $u .= $atSurrogateChar;

       # Domain name
       # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        $u .= strtoupper( substr( $email, $c++, 1 ));
        for(; $c < $cN; )
        {
            $ch = substr( $email, $c++, 1 );
            if( $ch == '.' ) $ch = strtoupper( substr( $email, $c++, 1 )); # collapse '.'

            $u .= $ch;
        }
        return $u;
    }



    # Hook for 'LoginPosted'.
    #
    static function loginPosted( $form )
    {
        global $wgRequest;
        $ret = true; # continue hook processing
        $email = $form->mEmail;
        if( MailishUtil::endsWith( $email, '@wiki' ))
        {
            global $wgPasswordSender;

           # Translate NAME@wiki to NAME.  The form NAME@wiki is designed to fool the
           # validator for the email field (it rejected the previous form .NAME).
           # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
            $name = substr( $email, 0, strlen($email) - 5 );

           # - - -
            $email = $wgPasswordSender; # should suffice, as these accounts are for local admins
            $form->mEmail = $email;
            $wgRequest->setVal( 'wpEmail', $email );
              # hack per 'wpName' below, though not sure it's needed for 'wpEmail'
        }
        else
        {
            if( !User::isValidEmailAddr( $email )) return $ret;
              # actually only checks for '@', though the new validator for the email field
              # introduced in 1.20 or 1.21 does that much already

           # Translate email address to mailish username.
           # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
            $name = self::emailToUsername( self::canonicalEmail( $email ));
        }
        $form->mUsername = $name;
        $wgRequest->setVal( 'wpName', $name );
          # Faking it back into the request as though input to the form in the first
          # place.  Ugly hack, but otherwise the 'Email new password' facility fails:
          # http://groups.google.com/group/votorola/t/8d9b3630b81b28e1
        return $ret;
    }


}