module cubeadm_undo
  use cubetools_structure
  use cube_types
  use cubedag_parameters
  use cubeadm_cubeid_types
  use cubeadm_messaging
  !
  public :: cubeadm_undo_command,cubeadm_undo_register
  private
  !
  type :: undo_comm_t
     type(option_t), pointer :: undo
  end type undo_comm_t
  type(undo_comm_t) :: comm
  !
  type undo_user_t
    integer(kind=iden_l) :: histid
  end type undo_user_t
  !
  type undo_prog_t
     integer(kind=iden_l) :: histid
  end type undo_prog_t
  !
contains
  !
  subroutine cubeadm_undo_register(error)
    !-------------------------------------------------------------------
    ! Register ADM\UNDO command and its options
    !-------------------------------------------------------------------
    logical, intent(inout) :: error
    !
    character(len=*), parameter :: comm_help = strg_id
    type(standard_arg_t) :: stdarg
    character(len=*), parameter :: rname='UNDO>REGISTER'
    !
    call cubeadm_message(admseve%trace,rname,'Welcome')
    !
    ! Command
    call cubetools_register_command(&
         'UNDO','[CommandID]',&
         'Undo a command and remove it from history',&
         'Without argument, undo the last command (i.e. remove the command &
         &from the history and delete the products which were created).'&
         //strg_cr//strg_cr//&
         'With a positive identifier as argument, undo the command &
         &according to its ID.'&
         //strg_cr//strg_cr//&
         'With a negative position as argument, undo the command &
         &according to its position from the end (0=last, -1=before last,&
         &etc).'&
         //strg_cr//strg_cr//&
         'It is not possible to undo a command whose output products &
         &where used as inputs to other commands.',&
         cubeadm_undo_command,&
         comm%undo,error)
    if (error) return
    call stdarg%register( &
         'COMMAND', &
         '[CommandID]',  &
         strg_id,&
         code_arg_optional, &
         error)
    if (error) return
    !
  end subroutine cubeadm_undo_register
  !
  subroutine cubeadm_undo_command(line,error)
    !-------------------------------------------------------------------
    ! Support routine for command UNDO
    !-------------------------------------------------------------------
    character(len=*), intent(in)    :: line
    logical,          intent(inout) :: error
    !
    type(undo_user_t) :: user
    type(undo_prog_t) :: prog
    character(len=*), parameter :: rname='UNDO>COMMAND'
    !
    call cubeadm_message(admseve%trace,rname,'Welcome')
    !
    call cubeadm_undo_parse(line,user,error)
    if (error) return
    call cubeadm_undo_history(user,prog,error)
    if (error) return
  end subroutine cubeadm_undo_command
  !
  subroutine cubeadm_undo_parse(line,user,error)
    use cubetools_disambiguate
    !-------------------------------------------------------------------
    ! Parsing facility for command
    !   UNDO
    !-------------------------------------------------------------------
    character(len=*),  intent(in)    :: line
    type(undo_user_t), intent(out)   :: user
    logical,           intent(inout) :: error
    !
    character(len=*), parameter :: rname='UNDO>PARSE'
    !
    call cubeadm_message(admseve%trace,rname,'Welcome')
    !
    user%histid = 0  ! 0=last (same as CubeID)
    call cubetools_getarg(line,comm%undo,1,user%histid,.not.mandatory,error)
    if (error) return
  end subroutine cubeadm_undo_parse
  !
  subroutine cubeadm_undo_history(user,prog,error)
    use cubedag_history
    !-------------------------------------------------------------------
    ! 
    !-------------------------------------------------------------------
    type(undo_user_t), intent(in)    :: user
    type(undo_prog_t), intent(out)   :: prog
    logical,           intent(inout) :: error
    !
    character(len=*), parameter :: rname='UNDO>MAIN'
    !
    call cubeadm_message(admseve%trace,rname,'Welcome')
    !
    call cubeadm_undo_user2prog(user,prog,error)
    if (error) return
    call cubedag_history_removecommand(prog%histid,error)
    if (error)  return
  end subroutine cubeadm_undo_history
  !
  subroutine cubeadm_undo_user2prog(user,prog,error)
    !-------------------------------------------------------------------
    ! 
    !-------------------------------------------------------------------
    type(undo_user_t), intent(in)    :: user
    type(undo_prog_t), intent(out)   :: prog
    logical,           intent(inout) :: error
    !
    character(len=*), parameter :: rname='UNDO>USER2PROG'
    !
    call cubeadm_message(admseve%trace,rname,'Welcome')
    !
    prog%histid = user%histid  ! >0 or <=0 resolved by
                               ! cubedag_history_removecommand itself
  end subroutine cubeadm_undo_user2prog
end module cubeadm_undo
