// OpenTween - Client of Twitter
// Copyright (c) 2014 kim_upsilon (@kim_upsilon) <https://upsilo.net/~upsilon/>
// All rights reserved.
//
// This file is part of OpenTween.
//
// This program is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 3 of the License, or (at your option)
// any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program. If not, see <http://www.gnu.org/licenses/>, or write to
// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
// Boston, MA 02110-1301, USA.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Xunit;
using Xunit.Extensions;

namespace OpenTween
{
    public class HashtagManageTest
    {
        // _isPermanent絡みの挙動が謎すぎて全然網羅できてない

        [Fact]
        public void InitHashtagHistory_Test()
        {
            var hashtags = new[] { "#foo", "#bar" };

            using var atDialog = new AtIdSupplement();
            using var hashDialog = new HashtagManage(atDialog, hashtags, "", false, false, false);
            hashDialog.RunSilent = true;

            Assert.Equal(new[] { "#foo", "#bar" }, hashDialog.HistoryHashList.Items.Cast<string>());
            Assert.Equal(new[] { "#foo", "#bar" }, hashDialog.HashHistories);
        }

        [Fact]
        public void InitHashtagHistory_EmptyTest()
        {
            var hashtags = Array.Empty<string>();

            using var atDialog = new AtIdSupplement();
            using var hashDialog = new HashtagManage(atDialog, hashtags, "", false, false, false);
            hashDialog.RunSilent = true;

            Assert.Empty(hashDialog.HistoryHashList.Items);
            Assert.Empty(hashDialog.HashHistories);
        }

        [Fact]
        public void AddHashtag_Test()
        {
            using var atDialog = new AtIdSupplement();
            using var hashDialog = new HashtagManage(atDialog, Array.Empty<string>(), "", false, false, false);
            hashDialog.RunSilent = true;

            TestUtils.FireEvent(hashDialog.AddButton, "Click"); // 「新規 (&N)」ボタン

            hashDialog.UseHashText.Text = "#OpenTween";

            TestUtils.FireEvent(hashDialog.PermOK_Button, "Click"); // 「詳細」グループ内の「OK」ボタン

            Assert.Equal(new[] { "#OpenTween" }, hashDialog.HistoryHashList.Items.Cast<string>());
            Assert.Equal(new[] { "#OpenTween" }, hashDialog.HashHistories);
        }

        [Fact]
        public void AddHashtag_FullWidthTest()
        {
            using var atDialog = new AtIdSupplement();
            using var hashDialog = new HashtagManage(atDialog, Array.Empty<string>(), "", false, false, false);
            hashDialog.RunSilent = true;

            TestUtils.FireEvent(hashDialog.AddButton, "Click"); // 「新規 (&N)」ボタン

            hashDialog.UseHashText.Text = "＃ほげほげ";

            TestUtils.FireEvent(hashDialog.PermOK_Button, "Click"); // 「詳細」グループ内の「OK」ボタン

            Assert.Equal(new[] { "#ほげほげ" }, hashDialog.HistoryHashList.Items.Cast<string>());
            Assert.Equal(new[] { "#ほげほげ" }, hashDialog.HashHistories);
        }

        [Fact]
        public void AddHashtag_CombiningCharacterSequenceTest()
        {
            // ハッシュタグを表す「#」の直後に結合文字 (濁点など) が続いた場合に対するテスト

            using var atDialog = new AtIdSupplement();
            using var hashDialog = new HashtagManage(atDialog, Array.Empty<string>(), "", false, false, false);
            hashDialog.RunSilent = true;

            TestUtils.FireEvent(hashDialog.AddButton, "Click"); // 「新規 (&N)」ボタン

            // どんちき└(＾ω＾ )┐♫ ┌( ＾ω＾)┘♫どんちき
            hashDialog.UseHashText.Text = "#゛t゛e゛s゛a゛b゛u゛";

            TestUtils.FireEvent(hashDialog.PermOK_Button, "Click"); // 「詳細」グループ内の「OK」ボタン

            Assert.Equal(new[] { "#゛t゛e゛s゛a゛b゛u゛" }, hashDialog.HistoryHashList.Items.Cast<string>());
            Assert.Equal(new[] { "#゛t゛e゛s゛a゛b゛u゛" }, hashDialog.HashHistories);
        }

        [Fact]
        public void AddHashtag_MultipleTest()
        {
            using var atDialog = new AtIdSupplement();
            using var hashDialog = new HashtagManage(atDialog, Array.Empty<string>(), "", false, false, false);
            hashDialog.RunSilent = true;

            TestUtils.FireEvent(hashDialog.AddButton, "Click"); // 「新規 (&N)」ボタン

            hashDialog.UseHashText.Text = "#foo #bar";

            TestUtils.FireEvent(hashDialog.PermOK_Button, "Click"); // 「詳細」グループ内の「OK」ボタン

            Assert.Equal(new[] { "#foo #bar" }, hashDialog.HistoryHashList.Items.Cast<string>());
            Assert.Equal(new[] { "#foo #bar" }, hashDialog.HashHistories);
        }

        [Fact]
        public void AddHashtag_InvalidTest()
        {
            using var atDialog = new AtIdSupplement();
            using var hashDialog = new HashtagManage(atDialog, Array.Empty<string>(), "", false, false, false);
            hashDialog.RunSilent = true;

            TestUtils.FireEvent(hashDialog.AddButton, "Click"); // 「新規 (&N)」ボタン

            hashDialog.UseHashText.Text = "hogehoge";

            TestUtils.FireEvent(hashDialog.PermOK_Button, "Click"); // 「詳細」グループ内の「OK」ボタン
                                                                    // 実際にはここでエラーメッセージが出る

            Assert.Empty(hashDialog.HistoryHashList.Items);
            Assert.Empty(hashDialog.HashHistories);
        }

        [Fact]
        public void EditHashtag_Test()
        {
            var hashtags = new[] { "#foo", "#bar" };

            using var atDialog = new AtIdSupplement();
            using var hashDialog = new HashtagManage(atDialog, hashtags, "", false, false, false);
            hashDialog.RunSilent = true;

            hashDialog.HistoryHashList.SelectedIndices.Add(0);

            TestUtils.FireEvent(hashDialog.EditButton, "Click"); // 「編集(&E)」ボタン

            hashDialog.UseHashText.Text = "#hoge";

            TestUtils.FireEvent(hashDialog.PermOK_Button, "Click"); // 「詳細」グループ内の「OK」ボタン

            Assert.Equal(new[] { "#hoge", "#bar" }, hashDialog.HistoryHashList.Items.Cast<string>());
            Assert.Equal(new[] { "#hoge", "#bar" }, hashDialog.HashHistories);
        }

        [Fact]
        public void DeleteHashtag_Test()
        {
            var hashtags = new[] { "#foo", "#bar" };

            using var atDialog = new AtIdSupplement();
            using var hashDialog = new HashtagManage(atDialog, hashtags, "", false, false, false);
            hashDialog.RunSilent = true;

            hashDialog.HistoryHashList.SelectedIndices.Add(1);

            TestUtils.FireEvent(hashDialog.DeleteButton, "Click"); // 「削除(&D)」ボタン

            Assert.Equal(new[] { "#foo" }, hashDialog.HistoryHashList.Items.Cast<string>());
            Assert.Equal(new[] { "#foo" }, hashDialog.HashHistories);
        }

        [Fact]
        public void DeleteHashtag_MultipleTest()
        {
            var hashtags = new[] { "#foo", "#bar", "#baz" };

            using var atDialog = new AtIdSupplement();
            using var hashDialog = new HashtagManage(atDialog, hashtags, "", false, false, false);
            hashDialog.RunSilent = true;

            hashDialog.HistoryHashList.SelectedIndices.Add(2);
            hashDialog.HistoryHashList.SelectedIndices.Add(1);

            TestUtils.FireEvent(hashDialog.DeleteButton, "Click"); // 「削除(&D)」ボタン

            Assert.Equal(new[] { "#foo" }, hashDialog.HistoryHashList.Items.Cast<string>());
            Assert.Equal(new[] { "#foo" }, hashDialog.HashHistories);
        }

        [Fact]
        public void DeleteHashtag_NotSelectTest()
        {
            var hashtags = new[] { "#foo", "#bar" };

            using var atDialog = new AtIdSupplement();
            using var hashDialog = new HashtagManage(atDialog, hashtags, "", false, false, false);
            hashDialog.RunSilent = true;

            // ハッシュタグを選択していない状態

            TestUtils.FireEvent(hashDialog.DeleteButton, "Click"); // 「削除(&D)」ボタン

            Assert.Equal(new[] { "#foo", "#bar" }, hashDialog.HistoryHashList.Items.Cast<string>());
            Assert.Equal(new[] { "#foo", "#bar" }, hashDialog.HashHistories);
        }

        [Fact]
        public void UnSelectButton_Test()
        {
            var hashtags = new[] { "#foo" };

            using var atDialog = new AtIdSupplement();
            using var hashDialog = new HashtagManage(atDialog, hashtags, "", false, false, false);
            hashDialog.RunSilent = true;

            hashDialog.HistoryHashList.SelectedIndices.Add(0);

            TestUtils.FireEvent(hashDialog.UnSelectButton, "Click"); // 「非使用(&U)」ボタン

            Assert.Empty(hashDialog.HistoryHashList.SelectedIndices);
        }

        [Fact]
        public void EditModeSwitch_Test()
        {
            using var atDialog = new AtIdSupplement();
            using var hashDialog = new HashtagManage(atDialog, Array.Empty<string>(), "", false, false, false);
            hashDialog.RunSilent = true;

            Assert.True(hashDialog.GroupHashtag.Enabled);
            Assert.True(hashDialog.TableLayoutButtons.Enabled);
            Assert.False(hashDialog.GroupDetail.Enabled);

            TestUtils.FireEvent(hashDialog.AddButton, "Click"); // 「新規 (&N)」ボタン

            // 編集モードに入る
            Assert.False(hashDialog.GroupHashtag.Enabled);
            Assert.False(hashDialog.TableLayoutButtons.Enabled);
            Assert.True(hashDialog.GroupDetail.Enabled);

            hashDialog.UseHashText.Text = "#hogehoge";

            TestUtils.FireEvent(hashDialog.PermOK_Button, "Click"); // 「詳細」グループ内の「OK」ボタン

            // 編集モードから抜ける
            Assert.True(hashDialog.GroupHashtag.Enabled);
            Assert.True(hashDialog.TableLayoutButtons.Enabled);
            Assert.False(hashDialog.GroupDetail.Enabled);
        }
    }
}
