using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CookComputing.XmlRpc;

namespace BTS.Trac
{
    /// <summary>
    /// XML-Trac.rpc I/F（名前と値のみのフィールド）
    /// </summary>
    public interface ITracNameAndValueField : IXmlRpcProxy
    {
        /// <summary>
        /// すべてのフィールドを取得する
        /// </summary>
        /// <returns>フィールド名称</returns>
        string[] GetAll();

        /// <summary>
        /// 指定されたフィールドの値を取得する
        /// </summary>
        /// <param name="name">フィールド名称</param>
        /// <returns>値</returns>
        string Get( string name );

        /// <summary>
        /// 指定されたフィールドを削除する
        /// </summary>
        /// <param name="name">削除するフィールド名称</param>
        /// <returns>処理結果</returns>
        int Delete( string name );

        /// <summary>
        /// フィールドを作成する
        /// </summary>
        /// <param name="name">作成するフィールド名称</param>
        /// <param name="value">作成する値</param>
        /// <returns>処理結果</returns>
        int Create( string name, string value );

        /// <summary>
        /// 指定されたフィールドを更新する
        /// </summary>
        /// <param name="name">更新するフィールド名称</param>
        /// <param name="value">更新する値</param>
        /// <returns>処理結果</returns>
        int Update( string name, string value );
    }


    /// <summary>
    /// 名前と値のみのフィールド
    /// </summary>
    public class TracNameAndValueField<T> where T : class, ITracNameAndValueField
    {
        /// <summary>
        /// XML-RPC I/F
        /// </summary>
        private static TracXmlRpcBase<T> rpc = new TracXmlRpcBase<T>();

        /// <summary>
        /// XML-RPC I/F
        /// </summary>
        private static T Rpc
        {
            get
            {
                lock ( rpc ) {
                    if ( string.IsNullOrEmpty( rpc.Url ) ) {
                        rpc.Create( Trac.XmlRpcUrl, Trac.UserName, Trac.Password );
                    }
                }

                return rpc.Content;
            }
        }

        /// <summary>
        /// フィールド名称
        /// </summary>
        public string Name
        {
            get;
            private set;
        }

        /// <summary>
        /// 順序
        /// </summary>
        public string Value
        {
            get;
            set;
        }

        /// <summary>
        /// コンストラクタ
        /// </summary>
        public TracNameAndValueField()
        {
            Name = "";
            Value = "";
        }

        /// <summary>
        /// コンストラクタ
        /// </summary>
        /// <param name="name">フィールド名称</param>
        public TracNameAndValueField( string name )
        {
            Get( name );
        }

        /// <summary>
        /// フィールドを取得
        /// </summary>
        /// <param name="name">フィールド名称</param>
        public void Get( string name )
        {
            string ret = Rpc.Get( name );

            Name = name;
            Value = ret;
        }

        /// <summary>
        /// フィールドの削除
        /// </summary>
        /// <returns>処理結果</returns>
        public void Delete()
        {
            Delete( Name );
        }

        /// <summary>
        /// フィールドの削除
        /// </summary>
        /// <param name="name">フィールド名称</param>
        public static void Delete( string name )
        {
            int ret = Rpc.Delete( name );
            if ( ret != 0 ) {
                throw new Exception( "ticketTypeDelete" );
            }
        }

        /// <summary>
        /// フィールドの作成
        /// </summary>
        /// <param name="name">フィールド名称</param>
        public void Create( string name )
        {
            int ret = Rpc.Create( name, Value );
            if ( ret != 0 ) {
                throw new Exception( "ticketTypeCreate" );
            }

            Name = name;
        }

        /// <summary>
        /// フィールドの更新
        /// </summary>
        public void Update()
        {
            int ret = Rpc.Update( Name, Value );
            if ( ret != 0 ) {
                throw new Exception( "ticketTypeUpdate" );
            }
        }

        /// <summary>
        /// フィールドの取得
        /// </summary>
        /// <returns>フィールド文字列</returns>
        public static string[] GetAll()
        {
            return Rpc.GetAll();
        }
    }
}
