context: //    CANAPE Network Testing Tool
  //    Copyright (C) 2014 Context Information Security
  //
  //    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/>.
  
  using System;
  using System.Collections.Generic;
  using System.ComponentModel;
  using System.IO;
  using System.Linq;
  using System.Windows.Forms;
  using CANAPE.Documents;
  using CANAPE.Documents.Net;
  using CANAPE.Extension;
  using CANAPE.Forms;
  using CANAPE.Net;
  using CANAPE.Nodes;
  using CANAPE.Utils;
  using System.Threading;
  using CANAPE.Security;
  using System.Threading.Tasks;
  
  namespace CANAPE.Controls.DocumentEditors
  {
      public partial class NetServiceDocumentControl : UserControl
      {
          private const string PACKETLOG_CONFIG = "PacketLogControlConfig";
  
          private class FileRedirectLogEntry
          {
              public string Name { get; private set; }
              public FilePacketLogger Logger { get; private set; }
  
              public FileRedirectLogEntry(string name, string fileName)
              {
                  Name = name;
                  Logger = new FilePacketLogger(fileName);
              }
          }
  
          protected ProxyNetworkService _service;
          protected ProxyNetworkService _repeaterService;
          protected NetServiceDocument _document;
          protected Control _serviceControl;
          private IReadOnlyControl _readOnlyControl;
          protected int _connId;
          private bool _enableRedirect;
          private Dictionary<Guid, FileRedirectLogEntry> _fileLogs;
          private long _currentLogIndex;        
  
          public static bool PacketLogMutable { get; set; }
  
          private string _defaultGraph;
  
          protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
          {
              bool ret = true;
  
              switch(keyData)
              {
                  case Keys.F5:
                      btnStart.PerformClick();
                      break;
                  default:
                      ret = base.ProcessCmdKey(ref msg, keyData);
                      break;
              }
  
              return ret;
          }
  
          private Type GetControlTypeForDocument(NetServiceDocument document)
          {
              foreach(var ext in DocumentEditorManager.Instance.GetExtensions())
              {
                  DocumentEditorAttribute attr = (DocumentEditorAttribute)ext.ExtensionAttribute;
  
                  if (ext.ExtensionAttribute.DocumentType == document.GetType())
                  {
                      return ext.ExtensionType;
                  }
              }
  
              if (document is FixedProxyDocument)
              {
                  return typeof(FixedProxyControl);
              }
              else if (document is SocksProxyDocument)
              {
                  return typeof(GenericProxyControl);
              }
              else if (document is HttpProxyDocument)
              {
                  return typeof(GenericProxyControl);
              }
              else if (document is NetServerDocument)
              {
                  return typeof(NetServerControl);
              }
              else if (document is NetAutoClientDocument)
              {
                  return typeof(NetAutoClientControl);
              }
              else if (document is FullHttpProxyDocument)
              {
                  return typeof(GenericProxyControl);
              }
  
              throw new ArgumentException("Unknown document type");
          }
  
          public NetServiceDocumentControl(NetServiceDocument document)
          {
              
              InitializeComponent();
              if (components == null)
              {
                  components = new Container();
              }
  
              _serviceControl = (Control)Activator.CreateInstance(GetControlTypeForDocument(document), document);            
              _readOnlyControl = _serviceControl as IReadOnlyControl;
              panelSettings.Controls.Add(_serviceControl);
              _serviceControl.Dock = DockStyle.Fill;
              _document = document;
              packetLogControl.LogName = _document.Name;
              packetLogControl.ReadOnly = !PacketLogMutable;
              packetLogControl.SetPackets(_document.Packets);
              metaEditorControl.Meta = _document.GlobalMeta;
              networkHistoryControl.SetDocument(_document);
              _defaultGraph = "Default";
              _fileLogs = new Dictionary<Guid, FileRedirectLogEntry>();
              Disposed += new EventHandler(NetServiceControl_Disposed);
              credentialsEditorControl.SetCredentials(_document.Credentials);
  
              PacketLogControlConfig config = document.GetProperty(PACKETLOG_CONFIG) as PacketLogControlConfig;
  
              if (config != null)
              {
                  packetLogControl.Config = config;
              }
  
              Text = _document.Name;
              UpdateNetgraphs();
  
              comboBoxNetgraph.SelectedItem = null;
  
              foreach (object item in comboBoxNetgraph.Items)
              {
                  NetGraphDocument doc = item as NetGraphDocument;
                  if (doc == _document.NetGraph)
                  {
                      comboBoxNetgraph.SelectedItem = item;
                      break;
                  }
              }
          }
  
          void NetServiceControl_Disposed(object sender, EventArgs e)
          {
              StopService();
          }
  
          EditPacketForm CreateEditor(EditPacketEventArgs e)
          {
              if (InvokeRequired)
              {
                  return (EditPacketForm)Invoke(new Func<EditPacketEventArgs, EditPacketForm>(CreateEditor), e);
              }
              else
              {
                  EditPacketForm frm = new EditPacketForm();
  
                  frm.Frame = e.Frame;
                  frm.Selector = e.SelectPath;
                  frm.DisplayColor = ColorValueConverter.ToColor(e.Color);
                  frm.DisplayTag = e.Tag;
                  frm.ShowDisableEditor = true;
                  frm.ShowReadOnly = true;
  
                  frm.Show();
  
                  frm.Activate();
  
                  return frm;
  
              }
          }
  
          void DisposeEditor(EditPacketForm frm)
          {
              if (InvokeRequired)
              {
                  Invoke(new Action<EditPacketForm>(DisposeEditor), frm);
              }
  
              else
              {
                  frm.Dispose();
              }
          }
  
          void _service_EditPacketEvent(object sender, EditPacketEventArgs e)
          {
  
gt:             EditPacketForm frm = CreateEditor(e);