/**
 * Package:	Online update
 * Summary:	Start update, display last update info, choose mode (auto|manual)
 * Authors:	Gabriele Strattner <gs@suse.de>
 *		Stefan Schubert <schubi@suse.de>
 *              Cornelius Schumacher <cschum@suse.de>
 */

{

  textdomain "online-update";

  import "Label";
  import "Mode";
  import "OnlineUpdate";
  import "Popup";
  import "Wizard";
  import "AutoOnlineUpdate";
  import "OnlineUpdateDialogs";

  include "inst_source_dialogs.ycp";

  map server = $[ "url": "" ];

   // Request username/password from user
   define map DisplayLoginPopup( string username, string password,
				        string headline, string message ) ``{
       map ret_map = $[];

       string usernameLabel = _("&Username:");

       UI::OpenDialog(
		  `opt(`decorated),
		  `HBox(
			`HSpacing(1),
			`VBox(
			      `Left(`Heading( headline )),
			      `VSpacing(0.2),
			      `Label( message ),
			      `Frame (_("Authentication Data"),
				      `VBox (
					     `HBox (
						    `HSpacing (0.5),
						    `TextEntry ( `id(`username), usernameLabel, username ),
						    `HSpacing (0.5)
						    ),
					     `HBox (
						    `HSpacing (0.5),
						    `Password ( `id(`password), _("&Password:"), password ),
						    `HSpacing (0.5)
						    ))),
			      `VSpacing(0.2),
			      `CheckBox(`id(`keep), _("&Keep Authentication Data"), false ),
			      `VSpacing(0.2),
                              `PushButton(`id(`clear), _("&Clear Inputs")),
                              `VSpacing(0.2),
			      `HBox(`PushButton(`id(`login), `opt(`default), _("&Login") ),
				    `PushButton(`id(`abort), Label::CancelButton() )
				    ),
			      `VSpacing(0.2)

			      ),
			`HSpacing(1)
			)
		  );

       UI::SetFocus( `id(`username) );

       any ret = `nil;

       do {
           ret = UI::UserInput();

           if ( ret == `login )
           {
	       ret_map = add(ret_map, "username", UI::QueryWidget(`id(`username), `Value));
	       ret_map = add(ret_map, "password", UI::QueryWidget(`id(`password), `Value));
	       ret_map = add(ret_map, "persistent", UI::QueryWidget(`id(`keep), `Value));
	       ret_map = add(ret_map, "login", true );
           }
           else if ( ret == `clear )
           {
               UI::ChangeWidget( `id(`username), `Value, "" );
               UI::ChangeWidget( `id(`password), `Value, "" );
           }
           else
           {
	       ret_map =  add(ret_map, "login", false);
           }
       } while ( ret == `clear );

       UI::CloseDialog();

       return ret_map;
   };


  define string GetPatches() ``{

    UI::OpenDialog( `opt( `decorated ),
      `VBox(
        `VSpacing( 0.2 ),
        `ProgressBar( `id( `progress ), _("Retrieving information about new updates...") ),
        `VSpacing( 0.2 ),
        `PushButton( `id( `abort ), Label::AbortButton() ),
        `VSpacing( 0.2 )
      )
    );

    Pkg::YouSetServer( server );

    string url = server["url"]:"";
    map parsed_url = URL::Parse (url);
    string protocol = parsed_url["scheme"]:"";
    boolean auth_set = false;
    map usermap = $[];
    if (protocol == "ftp" || protocol == "http" || protocol == "smb")
    {
	string username = parsed_url["user"]:"";
	string password = parsed_url["pass"]:"";
	auth_set = size (username) > 0;
	if (auth_set)
	{
	    usermap = $[
		"username" : username,
		"password" : password,
	   ];
	};
    }
    if (! auth_set)
    {
	usermap = Pkg::YouGetUserPassword();
    }

    y2error ("Server: %1", server);

    string err = Pkg::YouGetDirectory();

    y2error ("err: %1", err);

    if ( err == "login" ) {
      string username = usermap[ "username" ]:"";
      string password = usermap[ "password" ]:"";
      string headline = _("Authorization");
      string msg_string = _("Enter the registration data.");

      map registration_map = DisplayLoginPopup( username, password,
                                                headline, msg_string );

      if ( registration_map[ "login" ]: false ) {
        Pkg::YouSetUserPassword( registration_map[ "username" ]:"",
                                 registration_map[ "password" ]:"",
                                 registration_map[ "persistent" ]:false );
        err = "";
      } else {
        err = "abort";
      }
    }

    if ( err == "" ) {
      err = Pkg::YouRetrievePatchInfo( OnlineUpdate::reload,
                                       OnlineUpdate::signature_check );
    }

    UI::CloseDialog();

    return err;

  };


  /////////////////////////////////////////////////////////////////////////////////////
  // MAIN:
  /////////////////////////////////////////////////////////////////////////////////////


  boolean cd_update = OnlineUpdate::cd_update;

  list you_server_list = [ $[ "url": "", "name": _("User-Defined Location") ] ];

  string you_url = OnlineUpdate::you_url;

  y2milestone( "you_url: %1", you_url );

  map statusmap = Pkg::YouStatus();
  y2debug("status map: %1", statusmap );

  string mirrorListServer = lookup( statusmap, "mirrorurl", "www.suse.de" );

  string initMessage = "";
  if ( cd_update ) {
    initMessage = _("Initializing for CD update...");
    you_url = "cd:///";
  } else {
    initMessage = sformat( _("Getting a list of mirror servers...")/*, mirrorListServer*/ );
  }
  UI::OpenDialog(`opt(`decorated ),`Label( initMessage ));

  if ( size( you_url ) != 0 ) {
    server[ "url" ] = you_url;
    you_server_list = add( you_server_list, server );
  } else {
    symbol result = `retry;
    do {
      string err = Pkg::YouGetServers( you_server_list );
      if ( size( err ) == 0 ) {
        result = `ok;
      } else {
        y2error( "Get Servers: %1", err );
        if ( err == "get" ) {
          string text = _("Cannot fetch remote server list. Only user-defined patch
sources will be available.

Possible solution:
Check network connection.
");
          result = OnlineUpdateDialogs::IgnoreWarningPopup( text,
                                          sformat( _("URL: %1"), mirrorListServer ) + "<br>" +
                                          Pkg::LastErrorDetails() );
        } else if ( err == "read" ) {
          result = OnlineUpdateDialogs::IgnorePopup( _("Unable to read server list from disk."),
                                   Pkg::LastErrorDetails() );
        } else if ( err == "write" ) {
          result = OnlineUpdateDialogs::IgnorePopup( _("Could not write server list to disk."),
                                   Pkg::LastErrorDetails() );
        } else {
          result = OnlineUpdateDialogs::IgnorePopup( _("Error getting servers."),
                                   Pkg::LastErrorDetails() );        
        }
        if ( result == `abort )
	{
	    UI::CloseDialog();
	    return result;
	}
      }
    } while ( result == `retry );
  }

  UI::CloseDialog();

  string status_product = lookup( statusmap, "product", "unknown" );
  string status_version = lookup( statusmap, "version", "unknown" );
  string status_basearch = lookup( statusmap, "basearch", "unknown" );
  integer status_lastupdate = lookup( statusmap, "lastupdate", -1 );

  string lastupdateLabel = "";
  
  if ( status_lastupdate == -1 ) {
    lastupdateLabel = _("There was no update executed up to now.");
  } else if ( status_lastupdate == 0 ) {
    lastupdateLabel = _("Last successful update was performed less than one day ago.");
  } else {
    lastupdateLabel = _("Last successful update was performed %1 day ago.",
                        "Last successful update was performed %1 days ago.",
                        status_lastupdate );
  }

  list servers = [];
  integer i = 0;
  while ( i < size( you_server_list ) ) {
    map server = you_server_list[ i ]:$[];
    string name = server[ "name" ]:"";
    string url = server[ "url" ]:"";
    string text = "";
    if ( size( name ) == 0 ) text = url;
    else text = name;
    servers = add( servers, `item( `id( i ), text ) );
    i = i + 1;
  }

  boolean manualSelection = true;
  if ( OnlineUpdate::you_auto || 
       SCR::Read( .sysconfig.onlineupdate.YOU_MANUAL_SELECTION ) == "no") {
    manualSelection = false;
  }

  // layout main dialog

  term contents =
  `VBox(
      `VSpacing( 0.3 ),
      `HBox(
          `HWeight(1, `Empty()),
          `HWeight(10,
              `Frame ( _("System &Information"),
                  `VBox(
                      `VSpacing(0.3),
                      `HBox(`HSpacing(0.8),
                          `Left( `Label( sformat( lastupdateLabel , status_lastupdate ) ) )
                      ),
                      `VSpacing(0.5),
                      `HBox(`HSpacing(0.8),
                            `Left( `Label( sformat( _("Product: %1"), status_product ) ) ),
                            `HSpacing(0.8)
                      ),
                      `HBox(`HSpacing(0.8),
                          `Left( `Label( sformat( _("Version: %1"), status_version ) ) )
                      ),
//                      `HBox(`HSpacing(0.8),
//                          `Left( `Label( sformat( _("Base Architecture: %1"), status_basearch ) ) )
//                      ),
                      `VSpacing(0.3)
                  )
              )
          ),
          `HWeight(1, `Empty())
      ),
      `VSpacing(1.0),
      `HBox(
          `HWeight(1, `Empty()),
          `HWeight(10,
              `Frame (_("Update Configuration"),
                  `VBox(
                      `VSpacing(0.3),
                      `VSquash(
                          `HBox(
                              `HSpacing(0.8),
                              `HWeight(1,`Left(`ComboBox(`id(`server), `opt(`notify), _("&Installation source"), servers ))),
                              `HSpacing(1.2)
                      )),
                      `HBox(
                          `HSpacing(0.8),
                          `TextEntry( `id(`url), `opt(`notify), _("Location"), "" ),
                          `HSpacing(1.2)
                      ),
                      `HBox(
                          `HSpacing(0.8),
                          `PushButton( `id(`newserver), _("New Server...") ),
                          `PushButton( `id(`editserver), _("Edit Server...") ),
                          `HStretch()
                      ),
                      `VSpacing(0.3),
                      `HBox(`HSpacing(0.8),
                          `Left(`CheckBox(`id(`manual),
                                _("&Manually Select Patches"), manualSelection ) )
                      ),
                      `HBox(`HSpacing(0.8),
                          `Left(`CheckBox(`id(`reload),
                                _("&Reload All Patches from Server"), false ) )
                      ),
                      `VSpacing( 0.5 ),
                      `HBox(
                          `PushButton( `id( `automatic ),
                                 _("&Configure Fully Automatic Update...") )
                      ),
                      `VSpacing( 0.3 )
                  )
              )
          ),
          `HWeight(1, `Empty())
      ),
      `VSpacing( 0.5 )
  );

  string help_text = "";

  // helptext dialog online update start screen
  string help_part1 =  _("<p>YaST Online Update (YOU) is the easy way to get all recommended
patches and security fixes from a SuSE update server.
</p>
");

  string help_part2 =  _("<p>
If <b>Manually Select Patches</b> is checked, all available patches will be shown
from which to select the patches to install.<br>
If <b>Reload All Patches from Server</b> is checked, all patches will be fetched
from the server even when they already are locally available from a previous
download.
</p>
");

  string help_part3 =  _("<p>After clicking <b>New Server</b>, select a local
installation source instead of an FTP or HTTP server or select
another FTP or HTTP server. Click <b>Edit Server</b> to edit the location of the
selected server.</p>
");

  string help_part4 = _("<p>Clicking <b>Configure Fully Automatic Update</b>
opens a dialog in which to configure YOU to check for updates once a day
and automatically download and install updates when new ones are available
without the need of user interaction.</p>
");

  help_text = help_part1 + help_part2 + help_part3 + help_part4;

  Wizard::SetContents( _("Welcome to YaST Online Update"), contents, help_text,
                       false, true );

  Wizard::SetNextButton(`next, Label::NextButton() );
  Wizard::DisableBackButton();
  Wizard::EnableAbortButton();

  UI::ChangeWidget( `id(`server), `Value, 1 );

  server = you_server_list[ 1 ]:$[];
  UI::ChangeWidget( `id(`url), `Value, server[ "url" ]:"" );


  //  Loop for User Input ....

  symbol ret = `next;

  repeat {

      ret = (symbol)UI::UserInput();

      if ( ret == `cancel ) ret = `abort;

      OnlineUpdate::you_auto = !(boolean)UI::QueryWidget( `id( `manual ),
                                                          `Value );
      OnlineUpdate::reload = (boolean)UI::QueryWidget( `id( `reload ), `Value );

      // which server is selected from combo box installation source ?
      integer serverId = (integer)UI::QueryWidget(`id(`server), `Value );

      server = you_server_list[ serverId ]:$[];

      if ( ret == `server ) {
        UI::ChangeWidget( `id(`url), `Value, server[ "url" ]:"" );
      } else if ( ret == `url ) {
        if ( serverId != 0 ) {
          UI::ChangeWidget( `id(`server), `Value, 0 );
        }
      } else if ( ret == `newserver || ret == `editserver ) {
          string url = "";
          if ( ret == `editserver ) {
            url = (string)UI::QueryWidget( `id(`url), `Value );
          }
          url = editUrl( url );
          if ( size( url ) > 0 ) {
            UI::ChangeWidget( `id(`url), `Value, url );
            UI::ChangeWidget( `id(`server), `Value, 0 );
          }
      } else if ( ret == `automatic ) {
          OnlineUpdateDialogs::SetupAutomatic();
      } else if ( ret == `abort && OnlineUpdateDialogs::ConfirmAbortUpdate(`painless) ) {
          return  `abort;
      } else if (ret == `next) {
          if ( serverId == 0 ) {
	    string url = (string)UI::QueryWidget( `id( `url ), `Value );
	    if (substring (url, size (url) - 1, 1) != "/")
		url = url + "/";
            server[ "url" ] = url;
	    server[ "type" ] = "custom";
            you_server_list[ 0 ] = server;
          }
	  // Pkg::SetServer( server ) is called in GetPatches()
          string err = GetPatches();

          if ( size( err ) != 0 ) {
            y2error( "GetPatches err: %1", err );

            ret = `this;

            if ( err != "abort" ) {
              string msg = "";
              string details = Pkg::LastErrorDetails();
              if ( err == "login" ) {
                msg = _("Login failed. Check that you have provided
the correct user name and password.
");
              } else if ( err == "media" ) {
                if ( cd_update ) {
                  msg = _("Initialization failed. Check that
you have inserted the correct CD.
");
                  details = Pkg::LastError() + "\n" + details;
                } else {
	          msg = _("Initialization failed. Try again.
If failure continues, choose
another SuSE FTP/HTTP server.
");
                  details = Pkg::LastError() + "\n" + details;
                }
              } else if ( err == "sig" ) {
                  msg = _("Signature check for patch info files failed.
Cannot load patch information.
");
                  ret = `this;
              
                  UI::ChangeWidget( `id( `reload ), `Value, true );              
              } else if ( err == "url" ) {
                  msg = _("URL is invalid.");
              } else {
                  msg = _("Patch information retrieval failed.");
                  details = err + "\n" + details;
              }

              OnlineUpdateDialogs::ErrorPopup( msg, details );
            }
          } else {
            Pkg::YouSelectPatches();
          }
      } else {
        y2debug( "RET: %1", ret );
      }

  } until (ret == `back || ret == `next || ret == `again);

  y2debug("Return START: %1", ret );

  return ret;
}
