using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using AipGateway.AIP;

namespace AipGateway.Viewer
{
    public partial class FrmMain : Form
    {
        private AipConfig _aipConfig;
        private AipFileManager _aipFileManager = null;
        private BindingList<object> fileLabels = new BindingList<object>();
        private BindingList<object> policyLabels = new BindingList<object>();
        private BindingList<object> protectTemplates = new BindingList<object>();

        public FrmMain()
        {
            InitializeComponent();
            Initialize();
        }

        private void Initialize()
        {
            TxtLog.Clear();
        
            CboFileLabel.Items.Clear();
            CboPolicyLabel.Items.Clear();
            CboProtection.Items.Clear();
            CboAuthLoginType.SelectedIndex = -1;

            BtnEnabled(false);

            _aipConfig = new AipConfig
            {
                AppName = ConfigurationManager.AppSettings["AppName"], // 어플리케이션 이름
                AppVersion = ConfigurationManager.AppSettings["AppVersion"], // 어플리케이션 버전
                ClientId = ConfigurationManager.AppSettings["aip:ClientId"], // 어플리케이션 ID(클라이언트 ID)
                TenantId = ConfigurationManager.AppSettings["aip:TenantId"], // 디렉토리(테넌트) ID
                MipData = ConfigurationManager.AppSettings["aip:MipData"], // Mip Data Path
                Domain = ConfigurationManager.AppSettings["aip:Domain"], // Domain
                EMail = ConfigurationManager.AppSettings["aip:EMail"], // User E-Mail
                SecretValue = ConfigurationManager.AppSettings["aip:SecretValue"], // 인증 비밀번호
                CertThumbPrint = ConfigurationManager.AppSettings["aip:CertThumbPrint"] // 인증서 지문
            };
            string tempLoginType = ConfigurationManager.AppSettings["aip:LoginType"];
            AipAuthLoginType loginType = (AipAuthLoginType)Enum.Parse(typeof(AipAuthLoginType), tempLoginType, true);
            _aipConfig.LoginType = loginType;
            CboAuthLoginType.SelectedIndex = Convert.ToInt32(loginType);

            TxtAppName.Text = _aipConfig.AppName;
            TxtAppVer.Text = _aipConfig.AppVersion;
            TxtClientId.Text = _aipConfig.ClientId;
            TxtTenantId.Text = _aipConfig.TenantId;
            TxtMipData.Text = _aipConfig.MipData;
            TxtDomain.Text = _aipConfig.Domain;
            TxtEMail.Text = _aipConfig.EMail;
            TxtSecretValue.Text = _aipConfig.SecretValue;
            TxtCertThumbPrint.Text = _aipConfig.CertThumbPrint;

            TxtOwner.Text = _aipConfig.EMail;
        }

        private void BtnEnabled(bool initialized)
        {
            BtnInitialize.Enabled = !initialized;
            BtnSingOut.Enabled = initialized;
            BtnGetInfo.Enabled = initialized;
            BtnOutGetInfo.Enabled = initialized;
            BtnSetLabel.Enabled = initialized;
            BtnSetProtection.Enabled = initialized;

        }
        private void BtnFileSelect_Click(object sender, EventArgs e)
        {
            String inputFileName = ShowFileOpenDialog();
            TxtInputFile.Text = inputFileName;
            if (inputFileName != "")
            {
                string filePath = Path.GetDirectoryName(inputFileName);
                string fileName = Path.GetFileNameWithoutExtension(inputFileName);
                string fileExtension = Path.GetExtension(inputFileName);

                TxtActualFile.Text = filePath + Path.DirectorySeparatorChar + fileName + "-out" + fileExtension;
            }
            else
            {
                TxtActualFile.Text = "";
            }
        }
        private string ShowFileOpenDialog()
        {
            //파일오픈창 생성 및 설정
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Title = "AIP 테스트 파일 선택";
            //ofd.FileName = "test";
            ofd.Filter = "모든 파일 (*.*) | *.*";

            //파일 오픈창 로드
            DialogResult dr = ofd.ShowDialog();

            //OK버튼 클릭시
            if (dr == DialogResult.OK)
            {
                // File명과 확장자를 가지고 온다.
                string fileName = ofd.SafeFileName;
                // File경로와 File명을 모두 가지고 온다.
                string fileFullName = ofd.FileName;
                // File경로만 가지고 온다.
                string filePath = fileFullName.Replace(fileName, "");

                //File경로 + 파일명 리턴
                return fileFullName;
            }
            //취소버튼 클릭시 또는 ESC키로 파일창을 종료 했을경우
            else if (dr == DialogResult.Cancel)
            {
                return "";
            }

            return "";
        }

        private void BtnInitialize_Click(object sender, EventArgs e)
        {
            _aipConfig.AppName = TxtAppName.Text.Trim();
            _aipConfig.AppVersion = TxtAppVer.Text.Trim();
            _aipConfig.ClientId = TxtClientId.Text.Trim();
            _aipConfig.TenantId = TxtTenantId.Text.Trim();
            _aipConfig.MipData = TxtMipData.Text.Trim();
            _aipConfig.Domain = TxtDomain.Text.Trim();
            _aipConfig.EMail = TxtEMail.Text.Trim();
            _aipConfig.SecretValue = TxtSecretValue.Text.Trim();
            _aipConfig.CertThumbPrint = TxtCertThumbPrint.Text.Trim();
            int loginType = CboAuthLoginType.SelectedIndex;
            if (loginType < 0)
            {
                MessageBox.Show("인증 로그인 방법을 선택 하세요.", "Initialize Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                CboAuthLoginType.Focus();
                return;
            }
            _aipConfig.LoginType = (AipAuthLoginType)Enum.ToObject(typeof(AipAuthLoginType), loginType);

            SignOut();
            SignIn();
        }

        private void BtnSingOut_Click(object sender, EventArgs e)
        {
            SignOut();
        }

        private void SignIn()
        {
            _aipFileManager = new AipFileManager(_aipConfig);

            _aipFileManager.Initialize();
            _aipFileManager.CreateProfile();
            _aipFileManager.CreateEngine();

            StringBuilder sb = new StringBuilder();

            sb.AppendLine("SensitivityLabels(Label)===============================================");
            ComboboxItem item1 = new ComboboxItem("", "   --- Label ---");
            CboFileLabel.Items.Add(item1);

            List<AipLabel> aipLabels = _aipFileManager.SensitivityLabels();
            foreach (var label in aipLabels)
            {
                ComboboxItem item = new ComboboxItem(label.Id, label.Name);
                CboFileLabel.Items.Add(item);

                sb.AppendLine(string.Format("\tID: {0}, {1}, {2}", label.Id, label.Name, label.IsActive));
                if (label.Children.Count > 0)
                {
                    foreach (AipLabel child in label.Children)
                    {
                        ComboboxItem childItem = new ComboboxItem(child.Id, "\t" + child.Name);
                        CboFileLabel.Items.Add(childItem);
                        sb.AppendLine(string.Format("\t\tID: {0}, {1}, {2}", child.Id, child.Name, child.IsActive));
                    }
                }
            }
            CboFileLabel.SelectedIndex = 0;

            sb.AppendLine("ListSensitivityLabels(Policy)==========================================");
            ComboboxItem item2 = new ComboboxItem("", "   --- Sensitivity ---");
            CboPolicyLabel.Items.Add(item2);

            List<AipLabel> labels2 = _aipFileManager.ListSensitivityLabels();
            foreach (var v in labels2)
            {
                ComboboxItem item = new ComboboxItem(v.Id, v.Name);
                CboPolicyLabel.Items.Add(item);
                sb.AppendLine(string.Format("\tID: {0}, {1}, {2}", v.Id, v.Name, v.IsActive));
                if (v.Children.Count > 0)
                {
                    foreach (AipLabel child in v.Children)
                    {
                        ComboboxItem childItem = new ComboboxItem(child.Id, "\t" + child.Name);
                        CboPolicyLabel.Items.Add(childItem);
                        sb.AppendLine(string.Format("\t\tID: {0}, {1}, {2}", child.Id, child.Name, child.IsActive));
                    }
                }
            }
            CboPolicyLabel.SelectedIndex = 0;

            sb.AppendLine("GetTemplates(Protection)===============================================");
            ComboboxItem item3 = new ComboboxItem("", "   --- Templates ---");
            CboProtection.Items.Add(item3);

            List<AipTemplate> templates = _aipFileManager.GetTemplates();
            foreach (var v in templates)
            {
                ComboboxItem item = new ComboboxItem(v.Id, v.Name);
                CboProtection.Items.Add(item);
                sb.AppendLine(string.Format("\tID: {0}, {1}", v.Id, v.Name));
                // sb.AppendLine(string.Format("\tID: {0}, {1}, {2}", v.Id, v.Name, v.Description));
            }
            sb.AppendLine("=======================================================================");
            CboProtection.SelectedIndex = 0;
            TxtLog.Text = sb.ToString();

            BtnEnabled(true);
        }
        private void SignOut()
        {
            BtnEnabled(false);

            CboFileLabel.Items.Clear();
            CboPolicyLabel.Items.Clear();
            CboProtection.Items.Clear();

            if (_aipFileManager != null)
            {
                _aipFileManager = null;
            }
        }

        private void AppendLog(string log)
        {
            TxtLog.Text += log + "\r\n";
        }
        private void BtnLogClear_Click(object sender, EventArgs e)
        {
            TxtLog.Clear();
        }

        private void BtnGetInfo_Click(object sender, EventArgs e)
        {
            string inputFileName = TxtInputFile.Text.Trim();
            if (inputFileName.Equals(""))
            {
                AppendLog("파일을 선택하세요.");
                TxtInputFile.Focus();
                return;
            }

            GetFileInfo(inputFileName);
        }

        private void BtnOutGetInfo_Click(object sender, EventArgs e)
        {
            string inputFileName = TxtActualFile.Text.Trim();
            if (inputFileName.Equals(""))
            {
                AppendLog("파일을 선택하세요.");
                TxtActualFile.Focus();
                return;
            }

            GetFileInfo(inputFileName);
        }

        private void GetFileInfo(String fileName)
        {
            TxtLog.Clear();

            if (!File.Exists(fileName))
            {
                AppendLog("파일이 존재하지 않습니다: " + fileName);
                return;
            }

            AipFileInfo info = _aipFileManager.GetFileInfo(fileName);
            if (info == null)
            {
                AppendLog("파일정보를 읽어 오는데 실패하였습니다.");
                AppendLog(_aipFileManager.LastErrNo + ", " + _aipFileManager.LastErrMsg);
                return;
            }

            AppendLog("출력파일명: " + info.OutputFileName);
            if (info.Content == null)
            {
                AppendLog("ContentLabel: 정보없음.");
            }
            else
            {
                AppendLog("ContentLabel:......................................................................");
                AppendLog("                CreationTime: " + info.Content.CreationTime);
                AppendLog("            AssignmentMethod: " + info.Content.AssignmentMethod);
                AppendLog("                 IsProtected: " + info.Content.IsProtectionAppliedFromLabel);
                if (info.Label != null)
                {
                    AppendLog("+Label                    Id: " + info.Label.Id);
                    AppendLog("                        Name: " + info.Label.Name);
                    AppendLog("                 Sensitivity: " + info.Label.Sensitivity);
                    AppendLog("                 Description: " + info.Label.Description);
                    AppendLog("                    IsActive: " + info.Label.IsActive);
                    AppendLog("                ActionSource: " + info.Label.ActionSource);
                }
                else
                {
                    AppendLog("+                      Label: 정보없음.");
                }
            }
            if (info.Protection == null)
            {
                AppendLog("Protection: 정보없음.");
            }
            else
            {
                AppendLog("Protection:......................................................................");
                AppendLog("                  Owner: " + info.Protection.Owner);
                AppendLog("               IssuedTo: " + info.Protection.IssuedTo);
                AppendLog("        IsIssuedToOwner: " + info.Protection.IsIssuedToOwner);
                AppendLog("              ContentId: " + info.Protection.ContentId);
                AppendLog("UseDeprecatedAlgorithms: " + info.Protection.UseDeprecatedAlgorithms);
                AppendLog("  AuditedExtractAllowed: " + info.Protection.AuditedExtractAllowed);
                AppendLog("              BlockSize: " + info.Protection.BlockSize);
                if (info.Protection.ProtectionDescriptor != null)
                {
                    AppendLog("+Description            ProtectionType: " + info.Protection.ProtectionDescriptor.ProtectionType);
                    AppendLog("                            TemplateId: " + info.Protection.ProtectionDescriptor.TemplateId);
                    AppendLog("              LabelInformation LabelId: " + info.Protection.ProtectionDescriptor.LabelInformation.LabelId);
                    AppendLog("             LabelInformation TenantId: " + info.Protection.ProtectionDescriptor.LabelInformation.TenantId);
                    AppendLog("                               LabelId: " + info.Protection.ProtectionDescriptor.LabelId);
                    AppendLog("                                 Owner: " + info.Protection.ProtectionDescriptor.Owner);
                    AppendLog("                             ContentId: " + info.Protection.ProtectionDescriptor.ContentId);
                    AppendLog("                                  Name: " + info.Protection.ProtectionDescriptor.Name);
                    AppendLog("                           Description: " + info.Protection.ProtectionDescriptor.Description);
                    AppendLog("                    AllowOfflineAccess: " + info.Protection.ProtectionDescriptor.AllowOfflineAccess);
                    AppendLog("                              Referrer: " + info.Protection.ProtectionDescriptor.Referrer);
                    AppendLog("                     ContentValidUntil: " + info.Protection.ProtectionDescriptor.ContentValidUntil);
                    AppendLog("                          DoubleKeyUrl: " + info.Protection.ProtectionDescriptor.DoubleKeyUrl);
                }
                else
                {
                    AppendLog("+Description: 정보없음.");
                }
            }
        }

        private void BtnSetLabel_Click(object sender, EventArgs e)
        {
            ComboboxItem fileItem = (ComboboxItem)CboFileLabel.SelectedItem;
            ComboboxItem policyItem = (ComboboxItem)CboPolicyLabel.SelectedItem;
            ComboboxItem protectItem = (ComboboxItem)CboProtection.SelectedItem;

            TxtLog.Clear();
            String labelId = fileItem == null ? "" : (string)fileItem.Value;
            if (labelId == "")
            {
                AppendLog("레이블을 선택하세요.");
                CboFileLabel.Focus();
                return;
            }
            string inputFileName = TxtInputFile.Text.Trim();
            if (inputFileName.Equals(""))
            {
                AppendLog("입력 파일을 선택하세요.");
                TxtInputFile.Focus();
                return;
            }
            string outputFileName = TxtActualFile.Text.Trim();
            if (outputFileName.Equals(""))
            {
                AppendLog("출력 파일을 선택하세요.");
                TxtActualFile.Focus();
                return;
            }
            SetFileLabel(inputFileName, outputFileName, labelId);
        }

        private void BtnSetProtection_Click(object sender, EventArgs e)
        {
            ComboboxItem fileItem = (ComboboxItem)CboFileLabel.SelectedItem;
            ComboboxItem policyItem = (ComboboxItem)CboPolicyLabel.SelectedItem;
            ComboboxItem protectItem = (ComboboxItem)CboProtection.SelectedItem;

            TxtLog.Clear();
            String templateId = protectItem == null ? "" : (string)protectItem.Value;
            if (templateId == "")
            {
                AppendLog("프로텍션을 선택하세요.");
                CboProtection.Focus();
                return;
            }
            string inputFileName = TxtInputFile.Text.Trim();
            if (inputFileName.Equals(""))
            {
                AppendLog("입력 파일을 선택하세요.");
                TxtInputFile.Focus();
                return;
            }
            string outputFileName = TxtActualFile.Text.Trim();
            if (outputFileName.Equals(""))
            {
                AppendLog("출력 파일을 선택하세요.");
                TxtActualFile.Focus();
                return;
            }
            SetFileProtection(inputFileName, outputFileName, templateId);
        }

        private void BtnSetLabelAndProtection_Click(object sender, EventArgs e)
        {
            ComboboxItem fileItem = (ComboboxItem)CboFileLabel.SelectedItem;
            ComboboxItem policyItem = (ComboboxItem)CboPolicyLabel.SelectedItem;
            ComboboxItem protectItem = (ComboboxItem)CboProtection.SelectedItem;

            TxtLog.Clear();
            String labelId = fileItem == null ? "" : (string)fileItem.Value;
            if (labelId == "")
            {
                AppendLog("레이블을 선택하세요.");
                CboFileLabel.Focus();
                return;
            }
            String templateId = protectItem == null ? "" : (string)protectItem.Value;

        }

        private void SetFileLabel(string fileName, string actualFileName, string labelId)
        {
            if (!File.Exists(fileName))
            {
                AppendLog("파일이 존재하지 않습니다: " + fileName);
                return;
            }

            _aipFileManager.SetLabel(fileName, actualFileName, "SeungHo@kangfamily.site", labelId, "", "Test");
        }

        private void SetFileProtection(string fileName, string actualFileName, string templateId)
        {
            if (!File.Exists(fileName))
            {
                AppendLog("파일이 존재하지 않습니다: " + fileName);
                return;
            }

            _aipFileManager.SetProtection(fileName, actualFileName, "SeungHo@kangfamily.site", templateId, "Test");
        }

        private void button1_Click(object sender, EventArgs e)
        {
            string stringData = TxtLog.Text;
            byte[] dataArr = Encoding.UTF8.GetBytes(stringData);

            byte[] byteArr = Encoding.Unicode.GetBytes(stringData);
            AppendLog("======================================");
            AppendLog(Convert.ToBase64String(byteArr));

            string base64String = Convert.ToBase64String(dataArr);
            AppendLog("======================================");
            AppendLog(base64String);
        }
    }
}
