# -*- coding: utf-8 -*-
#
# alone : web application framework for small embedded systems.
#               Copyright (c) 2009-2010 Inas Co Ltd. All Rights Reserved.
#
# This file is destributed under BSD License. Please read the COPYRIGHT file.
#
# apache httpd用 digest認証ファイル編集サンプル
#
# 使用前に、model_htdigetst.rb に書かれた注意点を確認してください。

require 'al_form'
require 'al_template'
require './model_htdigest'


##
# Controller
#
class AlController

  ##
  # constructor
  #
  def initialize()
    @form = AlForm.new(
      AlText.new( 'username', :label=>'ユーザ名',
                  :required=>true, :validator=>/^[\w]+$/ ),
      AlText.new( 'realm', :label=>'レルム',
                  :required=>true, :validator=>/^[\w]+$/ ),
      AlPassword.new( 'password', :label=>'パスワード',
                  :required=>true, :validator=>/^[\w]+$/ ),
      AlSubmit.new( "submit1", :value=>"決定",
                    :tag_attr=> {:style=>"float: right;"} )
    )
    @form.action = Alone::make_uri( :action=>'commit' )
  end


  ##
  # デフォルトアクション
  #
  #@note
  # 登録ユーザ一覧を表示する
  #
  def action_index()
    @users = Htdigest::list()
    AlTemplate.run( 'v_index.rhtml' )
  end
  

  ##
  # 新規登録アクション
  #
  #@note
  # 空の登録フォームを表示
  #
  def action_createform()
    AlTemplate.run( 'v_form.rhtml' )
  end


  ##
  # 更新アクション
  #
  #@note
  # 更新用にフォームを調整してから表示
  #
  def action_updateform()
    if ! @form.validate( [:username, :realm] )
      return
    end
    @form.get_widget(:username).set_attr( :readonly=>'readonly' )
    @form.get_widget(:realm).set_attr( :readonly=>'readonly' )

    AlTemplate.run( 'v_form.rhtml' )
  end


  ##
  # 新規登録・更新の確定
  #
  #@note
  # フォームからのPOSTを受け取って、登録・更新を行い結果を表示。
  #
  def action_commit()
    if ! @form.validate()
      AlTemplate.run( 'v_form.rhtml' )
    else
      htd = Htdigest.new
      htd.values = @form.values
      htd.entry()

      Alone::redirect_to( Alone::make_uri() );
    end
  end


  ##
  # 1アカウントの削除実行
  #
  #@note
  #
  def action_delete_one()
    if ! @form.validate( [:username, :realm] )
      return
    end

    htd = Htdigest.new
    htd.values = @form.values
    htd.delete()

    Alone::redirect_to( Alone::make_uri() );
  end


  ##
  # チェックをつけたアカウントを一括削除
  #
  #@note
  # リスト全体がフォームになっているので（登録・編集フォームとは別）、
  # AlFormの機能を使ってPOSTされた値を取り出して処理する。
  # optionsは、username+realm のペアで、何が設定されるか予測できない。
  # そのため、fetch_request()からvalidate() を続けて行うことができず、
  # 少々ややこしいことをせざるをえない。
  # 
  # バリデーションを通った安全な値のみAlFormから取り出せるというポリシーが
  # あり、validate()を行わない場合はAlFormまで値が伝わらないので、ここでは
  # 一旦ウィジェットからバリデーション前の値を直接取り出している。
  #
  # :optionsに空Hashが指定されたときは、バリデーションしないという仕様に
  # する解決策も考えられる。しかし、ライブラリ使用者が validate()を通った
  # ことによる安心から、実は危険かもしれない値への注意をそいでしまうといっ
  # た懸念から、このままの仕様が望ましいだろう。
  #
  def action_delete_checked()
    # フォームを定義して、POSTされるべきデータ構造を明かにする。
    del_set = AlForm.new(
      AlCheckboxes.new( 'selected', :options=>{} )
    )

    # POSTされた値の取得
    if ! del_set.fetch_request()
      return action_index()             # チェックがなければリスト再表示
    end

    # 削除の実行
    values = del_set.get_widget(:selected).value
    values.each do |v|
      (u,r) = v.split('&')
      # 個別にバリデーションを行い、問題なければ削除実行
      @form.set_values( :username=>u, :realm=>r )
      if @form.validate( [:username, :realm] )
        htd = Htdigest.new
        htd.values = @form.values
        htd.delete()
      end
    end

    # リスト画面にもどる
    Alone::redirect_to( Alone::make_uri() );
  end
    
end
