<?php declare(strict_types = 0);
/*
** Copyright (C) 2001-2025 Zabbix SIA
**
** This program is free software: you can redistribute it and/or modify it under the terms of
** the GNU Affero General Public License as published by the Free Software Foundation, version 3.
**
** 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 Affero General Public License for more details.
**
** You should have received a copy of the GNU Affero General Public License along with this program.
** If not, see <https://www.gnu.org/licenses/>.
**/


use PHPUnit\Framework\TestCase;

class CImportDataAdapterTest extends TestCase {

	/**
	 * Cached XMl sources
	 *
	 * @var array
	 */
	protected $sources = [];

	public function testEmptyXml() {
		$adapter = $this->getAdapter($this->getEmptyXml());

		$this->assertEquals([], $adapter->getHostGroups());
		$this->assertEquals([], $adapter->getTemplateGroups());
		$this->assertEquals([], $adapter->getHosts());
		$this->assertEquals([], $adapter->getTemplates());
		$this->assertEquals([], $adapter->getItems());
		$this->assertEquals([], $adapter->getTriggers());
		$this->assertEquals([], $adapter->getGraphs());
		$this->assertEquals([], $adapter->getDiscoveryRules());
		$this->assertEquals([], $adapter->getImages());
		$this->assertEquals([], $adapter->getMaps());
		$this->assertEquals([], $adapter->getMediaTypes());
	}

	public function testGetGroups() {
		$adapter = $this->getAdapter($this->getHostAndTemplateXml());

		$this->assertEquals([
			[
				'name' => 'Linux servers',
				'uuid' => 'dc579cd7a1a34222933f24f52a68bcd8'
			],
			[
				'name' => 'Zabbix servers',
				'uuid' => '6f6799aa69e844b4b3918f779f2abf08'
			]
		], $adapter->getHostGroups());

		$this->assertEquals([
			[
				'name' => 'Templates',
				'uuid' => '7df96b18c230490a9a0a9e2307226338'
			]
		], $adapter->getTemplateGroups());
	}

	public function testGetHosts() {
		$adapter = $this->getAdapter($this->getHostAndTemplateXml());

		$this->assertEquals([
			[
				'inventory' => [],
				'monitored_by' => '0',
				'proxy' => [],
				'proxy_group' => [],
				'groups' => [
					[
						'name' => 'Linux servers'
					]
				],
				'templates' => [],
				'macros' => [],
				'interfaces' => [
					[
						'type' => '1',
						'useip' => '1',
						'ip' => '127.0.0.1',
						'dns' => '',
						'port' => '10050',
						'interface_ref' => 'if1',
						'details' => [],
						'main' => '1'
					]
				],
				'host' => 'empty-host',
				'status' => '0',
				'description' => '',
				'ipmi_authtype' => '-1',
				'ipmi_privilege' => '2',
				'ipmi_username' => '',
				'ipmi_password' => '',
				'name' => 'empty-host',
				'inventory_mode' => '0',
				'tags' => [],
				'valuemaps' => []
			],
			[
				'inventory' => [
					'type' => 'my-type',
					'type_full' => '',
					'name' => '',
					'alias' => '',
					'os' => '',
					'os_full' => '',
					'os_short' => '',
					'serialno_a' => '',
					'serialno_b' => '',
					'tag' => '',
					'asset_tag' => '',
					'macaddress_a' => '',
					'macaddress_b' => '',
					'hardware' => '',
					'hardware_full' => '',
					'software' => '',
					'software_full' => '',
					'software_app_a' => '',
					'software_app_b' => '',
					'software_app_c' => '',
					'software_app_d' => '',
					'software_app_e' => '',
					'contact' => '',
					'location' => '',
					'location_lat' => '',
					'location_lon' => '',
					'notes' => '',
					'chassis' => '',
					'model' => '',
					'hw_arch' => '',
					'vendor' => '',
					'contract_number' => '',
					'installer_name' => '',
					'deployment_status' => '',
					'url_a' => '',
					'url_b' => '',
					'url_c' => '',
					'host_networks' => '',
					'host_netmask' => '',
					'host_router' => '',
					'oob_ip' => '',
					'oob_netmask' => '',
					'oob_router' => '',
					'date_hw_purchase' => '',
					'date_hw_install' => '',
					'date_hw_expiry' => '',
					'date_hw_decomm' => '',
					'site_address_a' => '',
					'site_address_b' => '',
					'site_address_c' => '',
					'site_city' => '',
					'site_state' => '',
					'site_country' => '',
					'site_zip' => '',
					'site_rack' => '',
					'site_notes' => '',
					'poc_1_name' => '',
					'poc_1_email' => '',
					'poc_1_phone_a' => '',
					'poc_1_phone_b' => '',
					'poc_1_cell' => '',
					'poc_1_screen' => '',
					'poc_1_notes' => '',
					'poc_2_name' => '',
					'poc_2_email' => '',
					'poc_2_phone_a' => '',
					'poc_2_phone_b' => '',
					'poc_2_cell' => '',
					'poc_2_screen' => '',
					'poc_2_notes' => ''
				],
				'monitored_by' => '0',
				'proxy' => [],
				'proxy_group' => [],
				'groups' => [
						[
							'name' => 'Linux servers'
						]
					],
				'templates' => [
					[
						'name' => 'Template App FTP Service'
					],
					[
						'name' => 'Template OS Linux by Zabbix agent'
					]
				],
				'macros' => [
					[
						'macro' => '{$MACRO}',
						'value' => '2',
						'type' => '0',
						'description' => ''
					],
					[
						'macro' => '{$SNMP_COMMUNITY}',
						'value' => '1',
						'type' => '0',
						'description' => ''
					]
				],
				'interfaces' => [
					[
						'type' => '1',
						'useip' => '1',
						'ip' => '0.0.0.0',
						'dns' => '',
						'port' => '10050',
						'interface_ref' => 'if1',
						'details' => [],
						'main' => '1'
					],
					[
						'type' => '3',
						'useip' => '1',
						'ip' => '127.0.0.1',
						'dns' => '',
						'port' => '623',
						'interface_ref' => 'if4',
						'details' => [],
						'main' => '1'
					],
					[
						'type' => '4',
						'useip' => '1',
						'ip' => '127.0.0.1',
						'dns' => '',
						'port' => '12345',
						'interface_ref' => 'if3',
						'details' => [],
						'main' => '1'
					],
					[
						'type' => '2',
						'useip' => '1',
						'ip' => '127.0.0.1',
						'dns' => '',
						'port' => '161',
						'interface_ref' => 'if2',
						'details' => [
							'bulk' => '1',
							'version' => '2',
							'community' => '{$SNMP_COMMUNITY}',
							'max_repetitions' => '10',
							'contextname' => '',
							'securityname' => '',
							'securitylevel' => '0',
							'authprotocol' => '0',
							'authpassphrase' => '',
							'privprotocol' => '0',
							'privpassphrase' => ''
						],
						'main' => '1'
					]
				],
				'host' => 'export-host',
				'status' => '0',
				'description' => '',
				'ipmi_authtype' => '-1',
				'ipmi_privilege' => '2',
				'ipmi_username' => 'impi username',
				'ipmi_password' => 'impi password',
				'name' => 'export-host',
				'inventory_mode' => '0',
				'tags' => [],
				'valuemaps' => []
			]
		], $adapter->getHosts());
	}

	public function testGetTemplates() {
		$adapter = $this->getAdapter($this->getHostAndTemplateXml());

		$this->assertEquals([
			[
				'uuid' => 'c2fe64e562a040bd96333fb6b2de815a',
				'groups' => [
					[
						'name' => 'Templates'
					]
				],
				'macros' => [],
				'templates' => [],
				'host' => 'empty-template',
				'name' => 'empty-template',
				'description' => '',
				'vendor_name' => '',
				'vendor_version' => '',
				'tags' => [],
				'valuemaps' => []
			],
			[
				'uuid' => '00fda66f07e4479498058bf352711a06',
				'groups' =>	[
					[
						'name' => 'Templates'
					]
				],
				'macros' => [
					[
						'macro' => '{$MACRO}',
						'value' => '2',
						'type' => '0',
						'description' => ''
					],
					[
						'macro' => '{$SNMP_COMMUNITY}',
						'value' => '1',
						'type' => '0',
						'description' => ''
					]
				],
				'templates' => [
					[
						'name' => 'Template App FTP Service'
					],
					[
						'name' => 'Template OS Linux by Zabbix agent'
					]
				],
				'host' => 'export-template',
				'name' => 'export-template',
				'description' => '',
				'vendor_name' => '',
				'vendor_version' => '',
				'tags' => [],
				'valuemaps' => []
			]
		], $adapter->getTemplates());
	}

	public function testGetItems() {
		$adapter = $this->getAdapter($this->getHostAndTemplateXml());

		$this->assertEquals([
			'export-host' => [
				'item' => [
					'name' => 'item',
					'type' => (string) ITEM_TYPE_ZABBIX,
					'delay' => '30',
					'history' => '90d',
					'trends' => '365d',
					'status' => '0',
					'value_type' => '3',
					'units' => '',
					'description' => '',
					'inventory_link' => '0',
					'tags' => [],
					'valuemap' => [],
					'interface_ref' => 'if1',
					'triggers' => [],
					'key_' => 'item',
					'preprocessing' => [],
					'timeout' => ''
				],
				'item-jmx' => [
					'name' => 'item-jmx',
					'type' => (string) ITEM_TYPE_JMX,
					'delay' => '30',
					'history' => '90d',
					'trends' => '365d',
					'status' => '0',
					'value_type' => '3',
					'units' => '',
					'username' => '',
					'password' => '',
					'description' => '',
					'inventory_link' => '0',
					'tags' => [],
					'valuemap' => [],
					'interface_ref' => 'if3',
					'jmx_endpoint' => 'service:jmx:rmi:///jndi/rmi://{HOST.CONN}:{HOST.PORT}/jmxrmi',
					'triggers' => [],
					'key_' => 'item-jmx',
					'preprocessing' => []
				],
				'item2' => [
					'name' => 'item2',
					'type' => (string) ITEM_TYPE_ZABBIX,
					'delay' => '30',
					'history' => '90d',
					'trends' => '365d',
					'status' => '0',
					'value_type' => '3',
					'units' => '',
					'description' => '',
					'inventory_link' => '0',
					'tags' => [
						[
							'tag' => 'Application',
							'value' => 'app'
						]
					],
					'valuemap' => [],
					'interface_ref' => 'if1',
					'triggers' => [],
					'key_' => 'item2',
					'preprocessing' => [],
					'timeout' => ''
				]
			],
			'export-template' => [
				'item' => [
					'uuid' => 'cfe34a246c054d0483796f5bb71631b6',
					'name' => 'item',
					'type' => (string) ITEM_TYPE_ZABBIX,
					'delay' => '30',
					'history' => '90d',
					'trends' => '365d',
					'status' => '0',
					'value_type' => '3',
					'units' => '',
					'description' => '',
					'inventory_link' => '0',
					'tags' => [],
					'valuemap' => [],
					'triggers' => [],
					'key_' => 'item',
					'preprocessing' => [],
					'timeout' => ''
				],
				'item-jmx' => [
					'uuid' => '4164d2d034dc41ccb151a46b546110bc',
					'name' => 'item-jmx',
					'type' => (string) ITEM_TYPE_JMX,
					'delay' => '30',
					'history' => '90d',
					'trends' => '365d',
					'status' => '0',
					'value_type' => '3',
					'units' => '',
					'username' => '',
					'password' => '',
					'description' => '',
					'inventory_link' => '0',
					'tags' => [],
					'valuemap' => [],
					'jmx_endpoint' => 'service:jmx:rmi:///jndi/rmi://{HOST.CONN}:{HOST.PORT}/jmxrmi',
					'triggers' => [],
					'key_' => 'item-jmx',
					'preprocessing' => []
				],
				'item2' => [
					'uuid' => '3dc664d55caf4f008fb8d6db770d22e8',
					'name' => 'item2',
					'type' => (string) ITEM_TYPE_ZABBIX,
					'delay' => '30',
					'history' => '90d',
					'trends' => '365d',
					'status' => '0',
					'value_type' => '3',
					'units' => '',
					'description' => '',
					'inventory_link' => '0',
					'tags' => [
						[
							'tag' => 'Application',
							'value' => 'app'
						]
					],
					'valuemap' => [],
					'triggers' => [],
					'key_' => 'item2',
					'preprocessing' => [],
					'timeout' => ''
				]
			]
		], $adapter->getItems());
	}

	public function testGetTriggers() {
		$adapter = $this->getAdapter($this->getHostAndTemplateXml());

		$this->assertEquals([
			[
				'uuid' => 'ed06ed0623ef4e23bfd1a7e5e5ffce72',
				'expression' => 'last(/export-host/item)<>0',
				'recovery_mode' => (string) ZBX_RECOVERY_MODE_EXPRESSION,
				'recovery_expression' => '',
				'url' => '',
				'status' => '0',
				'priority' => '0',
				'type' => '0',
				'dependencies' =>[
					[
						'name' => 'trigger2',
						'expression' => 'last(/export-host/item)<>0',
						'recovery_expression' => ''
					]
				],
				'tags' => [],
				'correlation_mode' => (string) ZBX_TRIGGER_CORRELATION_NONE,
				'correlation_tag' => '',
				'event_name' => '',
				'opdata' => '',
				'url_name' => '',
				'manual_close' => (string) ZBX_TRIGGER_MANUAL_CLOSE_NOT_ALLOWED,
				'comments' => '',
				'description' => 'trigger'
			],
			[
				'uuid' => '6fbffaa155174cdd89e7f5a5999da9bf',
				'expression' => 'last(/export-host/item)<>0',
				'recovery_mode' => (string) ZBX_RECOVERY_MODE_EXPRESSION,
				'recovery_expression' => '',
				'url' => '',
				'status' => '0',
				'priority' => '0',
				'type' => '0',
				'dependencies' => [],
				'tags' => [],
				'correlation_mode' => (string) ZBX_TRIGGER_CORRELATION_NONE,
				'correlation_tag' => '',
				'event_name' => '',
				'opdata' => '',
				'url_name' => '',
				'manual_close' => (string) ZBX_TRIGGER_MANUAL_CLOSE_NOT_ALLOWED,
				'comments' => '',
				'description' => 'trigger2'
			],
			[
				'uuid' => 'c1046f1cf0c3434b979a374f66a17dfa',
				'expression' => 'last(/export-template/item)<>0',
				'recovery_mode' => (string) ZBX_RECOVERY_MODE_EXPRESSION,
				'recovery_expression' => '',
				'url' => '',
				'status' => '0',
				'priority' => '0',
				'type' => '0',
				'dependencies' =>[
					[
						'name' => 'trigger2',
						'expression' => 'last(/export-template/item)<>0',
						'recovery_expression' => ''
					]
				],
				'tags' => [],
				'correlation_mode' => (string) ZBX_TRIGGER_CORRELATION_NONE,
				'correlation_tag' => '',
				'event_name' => '',
				'opdata' => '',
				'url_name' => '',
				'manual_close' => (string) ZBX_TRIGGER_MANUAL_CLOSE_NOT_ALLOWED,
				'comments' => '',
				'description' => 'trigger'
			],
			[
				'uuid' => '3229895257e64d7399434434ccaa1f2d',
				'expression' => 'last(/export-template/item)<>0',
				'recovery_mode' => (string) ZBX_RECOVERY_MODE_EXPRESSION,
				'recovery_expression' => '',
				'url' => '',
				'status' => '0',
				'priority' => '0',
				'type' => '0',
				'dependencies' => [],
				'tags' => [],
				'correlation_mode' => (string) ZBX_TRIGGER_CORRELATION_NONE,
				'correlation_tag' => '',
				'event_name' => '',
				'opdata' => '',
				'url_name' => '',
				'manual_close' => (string) ZBX_TRIGGER_MANUAL_CLOSE_NOT_ALLOWED,
				'comments' => '',
				'description' => 'trigger2'
			]
		], $adapter->getTriggers());
	}

	public function testGetGraphs() {
		$adapter = $this->getAdapter($this->getHostAndTemplateXml());

		$this->assertEquals([
			[
				'uuid' => '0b6a0bf1bcf24329b51cc7633d229d9d',
				'name' => 'simple',
				'width' => '900',
				'height' => '200',
				'yaxismin' => '0.0000',
				'yaxismax' => '100.0000',
				'show_work_period' => '0',
				'show_triggers' => '0',
				'show_legend' => '1',
				'show_3d' => '0',
				'percent_left' => '0.0000',
				'percent_right' => '0.0000',
				'ymin_item_1' => '0',
				'ymax_item_1' => '0',
				'graphtype' => '0',
				'ymin_type' => '0',
				'ymax_type' => '0',
				'gitems' => [
					[
						'sortorder' => '0',
						'drawtype' => '0',
						'color' => '009900',
						'yaxisside' => '0',
						'calc_fnc' => '2',
						'type' => '0',
						'item' => [
							'host' => 'export-host',
							'key' => 'item'
						]
					]
				]
			],
			[
				'uuid' => 'c7579c89741d446db1c90fb5659be4a4',
				'name' => 'simple',
				'width' => '900',
				'height' => '200',
				'yaxismin' => '0.0000',
				'yaxismax' => '100.0000',
				'show_work_period' => '0',
				'show_triggers' => '0',
				'show_legend' => '1',
				'show_3d' => '0',
				'percent_left' => '0.0000',
				'percent_right' => '0.0000',
				'ymin_item_1' => '0',
				'ymax_item_1' => '0',
				'graphtype' => '0',
				'ymin_type' => '0',
				'ymax_type' => '0',
				'gitems' => [
					[
						'sortorder' => '0',
						'drawtype' => '0',
						'color' => '009900',
						'yaxisside' => '0',
						'calc_fnc' => '2',
						'type' => '0',
						'item' => [
							'host' => 'export-template',
							'key' => 'item'
						]
					]
				]
			]
		], $adapter->getGraphs());
	}

	public function testGetDiscoveryRules() {
		$adapter = $this->getAdapter($this->getHostAndTemplateXml());

		$this->assertEquals([
			'export-host' => [
				'empty-lld-rule' => [
					'name' => 'empty-lld-rule',
					'type' => (string) ITEM_TYPE_ZABBIX,
					'delay' => '30',
					'status' => '0',
					'filter' => [
						'evaltype' => (string) CONDITION_EVAL_TYPE_AND_OR,
						'conditions' => []
					],
					'lifetime' => '30d',
					'description' => '',
					'item_prototypes' => [],
					'trigger_prototypes' => [],
					'graph_prototypes' => [],
					'host_prototypes' => [],
					'interface_ref' => 'if1',
					'key_' => 'empty-lld-rule',
					'lld_macro_paths' => [],
					'preprocessing' => [],
					'timeout' => '',
					'overrides' => [],
					'lifetime_type' => (string) ZBX_LLD_DELETE_AFTER,
					'enabled_lifetime_type' => (string) ZBX_LLD_DELETE_NEVER
				],
				'empty-lld-rule-jmx' => [
					'name' => 'empty-lld-rule-jmx',
					'type' => (string) ITEM_TYPE_JMX,
					'delay' => '30',
					'status' => '0',
					'username' => '',
					'password' => '',
					'filter' => [
						'evaltype' => (string) CONDITION_EVAL_TYPE_AND_OR,
						'conditions' => []
					],
					'lifetime' => '30d',
					'description' => '',
					'item_prototypes' => [],
					'trigger_prototypes' => [],
					'graph_prototypes' => [],
					'host_prototypes' => [],
					'interface_ref' => 'if3',
					'jmx_endpoint' => 'service:jmx:rmi:///jndi/rmi://{HOST.CONN}:{HOST.PORT}/jmxrmi',
					'key_' => 'empty-lld-rule-jmx',
					'lld_macro_paths' => [],
					'preprocessing' => [],
					'overrides' => [],
					'lifetime_type' => (string) ZBX_LLD_DELETE_AFTER,
					'enabled_lifetime_type' => (string) ZBX_LLD_DELETE_NEVER
				],
				'lld-rule' => [
					'name' => 'lld-rule',
					'type' => (string) ITEM_TYPE_ZABBIX,
					'delay' => '30',
					'status' => '0',
					'filter' => [
						'evaltype' => (string) CONDITION_EVAL_TYPE_AND_OR,
						'conditions' => [
							[
								'macro' => '{#FSTYPE}',
								'value' => '1',
								'operator' => '8'
							],
							[
								'macro' => '{#FSTYPE2}',
								'value' => '2',
								'operator' => '8'
							]
						]
					],
					'lifetime' => '30d',
					'interface_ref' => 'if1',
					'description' => '',
					'item_prototypes' => [
						[
							'name' => 'lld-item',
							'type' => (string) ITEM_TYPE_ZABBIX,
							'discover' => '0',
							'delay' => '30',
							'history' => '90d',
							'trends' => '365d',
							'status' => '0',
							'value_type' => '3',
							'units' => '',
							'description' => '',
							'tags' => [],
							'valuemap' => [],
							'interface_ref' => 'if1',
							'key_' => 'lld-item',
							'trigger_prototypes' => [],
							'preprocessing' => [],
							'timeout' => ''
						],
						[
							'name' => 'lld-item-jmx',
							'type' => (string) ITEM_TYPE_JMX,
							'discover' => '0',
							'delay' => '30',
							'history' => '90d',
							'trends' => '365d',
							'status' => '0',
							'value_type' => '3',
							'units' => '',
							'username' => '',
							'password' => '',
							'description' => '',
							'tags' => [],
							'valuemap' => [],
							'interface_ref' => 'if3',
							'jmx_endpoint' => 'service:jmx:rmi:///jndi/rmi://{HOST.CONN}:{HOST.PORT}/jmxrmi',
							'key_' => 'lld-item-jmx',
							'trigger_prototypes' => [],
							'preprocessing' => []
						],
						[
							'name' => 'lld-item2',
							'type' => (string) ITEM_TYPE_ZABBIX,
							'discover' => '0',
							'delay' => '30',
							'history' => '90d',
							'trends' => '365d',
							'status' => '0',
							'value_type' => '3',
							'units' => '',
							'description' => '',
							'tags' => [
								[
									'tag' => 'Application',
									'value' => 'app'
								]
							],
							'valuemap' => [],
							'interface_ref' => 'if1',
							'key_' => 'lld-item2',
							'trigger_prototypes' => [],
							'preprocessing' => [],
							'timeout' => ''
						]
					],
					'trigger_prototypes' => [
						[
							'expression' => 'last(/export-host/lld-item)=0',
							'description' => 'lld-trigger',
							'url' => '',
							'discover' => '0',
							'status' => '0',
							'priority' => '0',
							'comments' => '',
							'type' => '0',
							'recovery_expression' => '',
							'recovery_mode' => (string) ZBX_RECOVERY_MODE_EXPRESSION,
							'tags' => [],
							'correlation_mode' => (string) ZBX_TRIGGER_CORRELATION_NONE,
							'correlation_tag' => '',
							'event_name' => '',
							'opdata' => '',
							'url_name' => '',
							'manual_close' => (string) ZBX_TRIGGER_MANUAL_CLOSE_NOT_ALLOWED,
							'dependencies' => []
						]
					],
					'graph_prototypes' => [
						[
							'name' => 'lld-graph',
							'width' => '900',
							'height' => '200',
							'yaxismin' => '0.0000',
							'yaxismax' => '100.0000',
							'show_work_period' => '1',
							'show_triggers' => '1',
							'show_legend' => '1',
							'show_3d' => '0',
							'percent_left' => '0.0000',
							'percent_right' => '0.0000',
							'ymin_item_1' => '0',
							'ymax_item_1' => '0',
							'discover' => '0',
							'graphtype' => '0',
							'ymin_type' => '0',
							'ymax_type' => '0',
							'gitems' => [
								[
									'sortorder' => '0',
									'drawtype' => '0',
									'color' => '00C800',
									'yaxisside' => '0',
									'calc_fnc' => '2',
									'type' => '0',
									'item' => [
										'host' => 'export-host',
										'key' => 'lld-item'
									]
								]
							]
						]
					],
					'host_prototypes' => [
						[
							'host' => '{#VMID}',
							'name' => '{#VMID}',
							'status' => '0',
							'group_links' => [
								[
									'group' => [
										'name' => 'Zabbix servers'
									]
								]
							],
							'group_prototypes' => [
								[
									'name' => '{#VMNAME}'
								]
							],
							'discover' => '0',
							'inventory_mode' => '0',
							'templates' => [],
							'macros' => [],
							'tags' => [],
							'custom_interfaces' => '0'
						]
					],
					'key_' => 'lld-rule',
					'lld_macro_paths' => [],
					'preprocessing' => [],
					'timeout' => '',
					'overrides' => [],
					'lifetime_type' => (string) ZBX_LLD_DELETE_AFTER,
					'enabled_lifetime_type' => (string) ZBX_LLD_DELETE_NEVER
				]
			],
			'export-template' => [
				'empty-lld-rule' => [
					'uuid' => '6ff04b5a5e8443c7aa9d5ce5f60ea4f9',
					'name' => 'empty-lld-rule',
					'type' => (string) ITEM_TYPE_ZABBIX,
					'delay' => '30',
					'status' => '0',
					'filter' => [
						'evaltype' => (string) CONDITION_EVAL_TYPE_AND_OR,
						'conditions' => []
					],
					'lifetime' => '30d',
					'description' => '',
					'item_prototypes' => [],
					'trigger_prototypes' => [],
					'graph_prototypes' => [],
					'host_prototypes' => [],
					'key_' => 'empty-lld-rule',
					'lld_macro_paths' => [],
					'preprocessing' => [],
					'timeout' => '',
					'overrides' => [],
					'lifetime_type' => (string) ZBX_LLD_DELETE_AFTER,
					'enabled_lifetime_type' => (string) ZBX_LLD_DELETE_NEVER
				],
				'lld-rule-jmx' => [
					'uuid' => '96c257b7f1104833ad3bb18f6a2e8d96',
					'name' => 'lld-rule-jmx',
					'type' => (string) ITEM_TYPE_JMX,
					'delay' => '30',
					'status' => '0',
					'username' => '',
					'password' => '',
					'filter' => [
						'evaltype' => (string) CONDITION_EVAL_TYPE_AND_OR,
						'conditions' => []
					],
					'lifetime' => '30d',
					'description' => '',
					'item_prototypes' => [],
					'trigger_prototypes' => [],
					'graph_prototypes' => [],
					'host_prototypes' => [],
					'jmx_endpoint' => 'service:jmx:rmi:///jndi/rmi://{HOST.CONN}:{HOST.PORT}/jmxrmi',
					'key_' => 'lld-rule-jmx',
					'lld_macro_paths' => [],
					'preprocessing' => [],
					'overrides' => [],
					'lifetime_type' => (string) ZBX_LLD_DELETE_AFTER,
					'enabled_lifetime_type' => (string) ZBX_LLD_DELETE_NEVER
				],
				'lld-rule' => [
					'uuid' => 'cdcd6fb3277e481baa22573c8c349b3b',
					'name' => 'lld-rule',
					'type' => (string) ITEM_TYPE_ZABBIX,
					'delay' => '30',
					'status' => '0',
					'filter' => [
						'evaltype' => (string) CONDITION_EVAL_TYPE_AND_OR,
						'conditions' => [
							[
								'macro' => '{#FSTYPE}',
								'value' => '1',
								'operator' => '8'
							],
							[
								'macro' => '{#FSTYPE2}',
								'value' => '2',
								'operator' => '8'
							]
						]
					],
					'lifetime' => '30d',
					'description' => '',
					'item_prototypes' => [
						[
							'uuid' => '2d2820fb2c2244df8dc75c92b2fc0f52',
							'name' => 'lld-item',
							'type' => (string) ITEM_TYPE_ZABBIX,
							'discover' => '0',
							'delay' => '30',
							'history' => '90d',
							'trends' => '365d',
							'status' => '0',
							'value_type' => '3',
							'units' => '',
							'description' => '',
							'tags' => [],
							'valuemap' => [],
							'preprocessing' => [],
							'timeout' => '',
							'key_' => 'lld-item',
							'trigger_prototypes' => []
						],
						[
							'uuid' => 'd51ab907cd2840d99a1deda0bc6ba887',
							'name' => 'lld-item-jmx',
							'type' => (string) ITEM_TYPE_JMX,
							'discover' => '0',
							'delay' => '30',
							'history' => '90d',
							'trends' => '365d',
							'status' => '0',
							'value_type' => '3',
							'units' => '',
							'username' => '',
							'password' => '',
							'description' => '',
							'tags' => [],
							'valuemap' => [],
							'jmx_endpoint' => 'service:jmx:rmi:///jndi/rmi://{HOST.CONN}:{HOST.PORT}/jmxrmi',
							'preprocessing' => [],
							'key_' => 'lld-item-jmx',
							'trigger_prototypes' => []
						],
						[
							'uuid' => '350f8c141fd94a8385a83a3dca077126',
							'name' => 'lld-item2',
							'type' => (string) ITEM_TYPE_ZABBIX,
							'discover' => '0',
							'delay' => '30',
							'history' => '90d',
							'trends' => '365d',
							'status' => '0',
							'value_type' => '3',
							'units' => '',
							'description' => '',
							'tags' => [
								[
									'tag' => 'Application',
									'value' => 'app'
								]
							],
							'valuemap' => [],
							'preprocessing' => [],
							'timeout' => '',
							'key_' => 'lld-item2',
							'trigger_prototypes' => []
						]
					],
					'trigger_prototypes' => [
						[
							'uuid' => '4650de0e6c2e4bfe8abe5a4225b477db',
							'expression' => 'last(/export-template/lld-item)=0',
							'description' => 'lld-trigger',
							'url' => '',
							'discover' => '0',
							'status' => '0',
							'priority' => '0',
							'comments' => '',
							'type' => '0',
							'recovery_mode' => (string) ZBX_RECOVERY_MODE_EXPRESSION,
							'recovery_expression' => '',
							'correlation_mode' => (string) ZBX_TRIGGER_CORRELATION_NONE,
							'correlation_tag' => '',
							'event_name' => '',
							'opdata' => '',
							'url_name' => '',
							'tags' => [],
							'manual_close' => (string) ZBX_TRIGGER_MANUAL_CLOSE_NOT_ALLOWED,
							'dependencies' => []
						]
					],
					'graph_prototypes' => [
						[
							'uuid' => '0d284e97f2724d1ca5b6ddf1f8cadf1a',
							'name' => 'lld-graph',
							'width' => '900',
							'height' => '200',
							'yaxismin' => '0.0000',
							'yaxismax' => '100.0000',
							'show_work_period' => '1',
							'show_triggers' => '1',
							'show_legend' => '1',
							'show_3d' => '0',
							'percent_left' => '0.0000',
							'percent_right' => '0.0000',
							'ymin_item_1' => '0',
							'ymax_item_1' => '0',
							'discover' => '0',
							'graphtype' => '0',
							'ymin_type' => '0',
							'ymax_type' => '0',
							'gitems' => [
								[
									'sortorder' => '0',
									'drawtype' => '0',
									'color' => '00C800',
									'yaxisside' => '0',
									'calc_fnc' => '2',
									'type' => '0',
									'item' => [
										'host' => 'export-template',
										'key' => 'lld-item'
									]
								]
							]
						]
					],
					'host_prototypes' => [
						[
							'uuid' => '63c71dad71754b1c8746ba88679ecd89',
							'host' => '{#VMID}',
							'name' => '{#VMID}',
							'status' => '0',
							'group_links' => [
								[
									'group' => [
										'name' => 'Zabbix servers'
									]
								]
							],
							'group_prototypes' => [
								[
									'name' => '{#VMNAME}'
								]
							],
							'discover' => '0',
							'templates' => [],
							'macros' => [],
							'tags' => [],
							'custom_interfaces' => '0',
							'inventory_mode' => '-1'
						]
					],
					'key_' => 'lld-rule',
					'lld_macro_paths' => [],
					'preprocessing' => [],
					'timeout' => '',
					'overrides' => [],
					'lifetime_type' => (string) ZBX_LLD_DELETE_AFTER,
					'enabled_lifetime_type' => (string) ZBX_LLD_DELETE_NEVER
				]
			]
		], $adapter->getDiscoveryRules());
	}

	public function testGetImages() {
		$adapter = $this->getAdapter($this->getMapXml());

		$this->assertEquals([
			[
				'name' => 'Server_(96)',
				'imagetype' => '1',
				'image' => ' '
			]
		], $adapter->getImages());
	}

	public function testGetMaps() {
		$adapter = $this->getAdapter($this->getMapXml());

		$this->assertEquals([
			[
				'name' => 'empty-map',
				'width' => '800',
				'height' => '600',
				'label_type' => '0',
				'label_location' => '0',
				'highlight' => '0',
				'expandproblem' => '0',
				'markelements' => '0',
				'show_unack' => '0',
				'severity_min' => '0',
				'show_suppressed' => '0',
				'grid_size' => '50',
				'grid_show' => '1',
				'grid_align' => '1',
				'label_format' => '0',
				'label_type_host' => '2',
				'label_type_hostgroup' => '2',
				'label_type_trigger' => '2',
				'label_type_map' => '2',
				'label_type_image' => '2',
				'label_string_host' => '',
				'label_string_hostgroup' => '',
				'label_string_trigger' => '',
				'label_string_map' => '',
				'label_string_image' => '',
				'expand_macros' => '0',
				'background' => [
					'name' => ''
				],
				'iconmap' => [
					'name' => ''
				],
				'urls' => [],
				'selements' => [],
				'links' => [],
				'shapes' => [[
					'type' => 0,
					'x' => '0',
					'y' => '0',
					'width' => '800',
					'height' => 15,
					'text' => '{MAP.NAME}',
					'font' => '9',
					'font_size' => '11',
					'font_color' => '000000',
					'text_halign' => '0',
					'text_valign' => '0',
					'border_type' => '0',
					'border_width' => '1',
					'border_color' => '000000',
					'background_color' => '',
					'zindex' => '0'
				]],
				'lines' => []
			],
			[
				'name' => 'map',
				'width' => '800',
				'height' => '600',
				'label_type' => '0',
				'label_location' => '0',
				'highlight' => '0',
				'expandproblem' => '0',
				'markelements' => '0',
				'show_unack' => '0',
				'severity_min' => '0',
				'show_suppressed' => '0',
				'grid_size' => '50',
				'grid_show' => '1',
				'grid_align' => '1',
				'label_format' => '0',
				'label_type_host' => '2',
				'label_type_hostgroup' => '2',
				'label_type_trigger' => '2',
				'label_type_map' => '2',
				'label_type_image' => '2',
				'label_string_host' => '',
				'label_string_hostgroup' => '',
				'label_string_trigger' => '',
				'label_string_map' => '',
				'label_string_image' => '',
				'expand_macros' => '0',
				'background' => [
					'name' => ''
				],
				'iconmap' => [
					'name' => ''
				],
				'urls' => [
					[
						'name' => 'url',
						'url' => 'http://google.com',
						'elementtype' => '0'
					]
				],
				'selements' => [
					[
						'elementtype' => '2',
						'label' => 'New element',
						'label_location' => '-1',
						'x' => '239',
						'y' => '127',
						'elementsubtype' => '0',
						'areatype' => '0',
						'width' => '200',
						'height' => '200',
						'viewtype' => '0',
						'use_iconmap' => '0',
						'selementid' => '32',
						'icon_off' => [
							'name' => 'Server_(96)'
						],
						'icon_on' => [
							'name' => ''
						],
						'icon_disabled' => [
							'name' => ''
						],
						'icon_maintenance' => [
							'name' => ''
						],
						'evaltype' => TAG_EVAL_TYPE_AND_OR,
						'tags' => [],
						'urls' => [
							[
								'name' => 'url',
								'url' => 'http://google.com'
							]
						],
						'elements' => [
							[
								'description' => 'trigger',
								'expression' => 'last(/export-host/item)<>0 or last(/export-host/item)<>0 and last(/export-host/item)<>0',
								'recovery_expression' => ''
							]
						]
					],
					[
						'elementtype' => '0',
						'label' => 'New element',
						'label_location' => '-1',
						'x' => '489',
						'y' => '127',
						'elementsubtype' => '0',
						'areatype' => '0',
						'width' => '200',
						'height' => '200',
						'viewtype' => '0',
						'use_iconmap' => '0',
						'selementid' => '33',
						'icon_off' => [
							'name' => 'Server_(96)'
						],
						'icon_on' => [
							'name' => ''
						],
						'icon_disabled' => [
							'name' => ''
						],
						'icon_maintenance' => [
							'name' => ''
						],
						'evaltype' => TAG_EVAL_TYPE_AND_OR,
						'tags' => [],
						'urls' => [],
						'elements' => [
							[
								'host' => 'export-host'
							]
						]
					],
					[
						'elementtype' => '3',
						'label' => 'New element',
						'label_location' => '-1',
						'x' => '239',
						'y' => '377',
						'elementsubtype' => '0',
						'areatype' => '0',
						'width' => '200',
						'height' => '200',
						'viewtype' => '0',
						'use_iconmap' => '0',
						'selementid' => '34',
						'icon_off' => [
							'name' => 'Server_(96)'
						],
						'icon_on' => [
							'name' => ''
						],
						'icon_disabled' => [
							'name' => ''
						],
						'icon_maintenance' => [
							'name' => ''
						],
						'evaltype' => TAG_EVAL_TYPE_AND_OR,
						'tags' => [],
						'urls' => [],
						'elements' => [
							[
								'name' => 'Zabbix servers'
							]
						]
					]
				],
				'links' => [
					[
						'drawtype' => '0',
						'color' => '00CC00',
						'label' => '',
						'selementid1' => '32',
						'selementid2' => '33',
						'linktriggers' => [
							[
								'drawtype' => '0',
								'color' => 'DD0000',
								'trigger' => [
									'description' => 'trigger',
									'expression' => 'last(/export-host/item)<>0 or last(/export-host/item)<>0 and last(/export-host/item)<>0',
									'recovery_expression' => ''
								]
							]
						]
					],
					[
						'drawtype' => '0',
						'color' => '00CC00',
						'label' => '',
						'selementid1' => '32',
						'selementid2' => '34',
						'linktriggers' => []
					]
				],
				'shapes' => [[
					'type' => 0,
					'x' => '0',
					'y' => '0',
					'width' => '800',
					'height' => 15,
					'text' => '{MAP.NAME}',
					'font' => '9',
					'font_size' => '11',
					'font_color' => '000000',
					'text_halign' => '0',
					'text_valign' => '0',
					'border_type' => '0',
					'border_width' => '1',
					'border_color' => '000000',
					'background_color' => '',
					'zindex' => '0'
				]],
				'lines' => []
			]
		], $adapter->getMaps());
	}

	public function testGetMediaTypes() {
		$adapter = $this->getAdapter($this->getMediaTypeXml());

		$defaults = DB::getDefaults('media_type') + ['message_templates' => []];

		$this->assertEquals([
			[
				'name' => 'Email',
				'type' => (string) CXmlConstantValue::MEDIA_TYPE_EMAIL,
				'provider' => (string) CXmlConstantValue::GENERIC_SMTP,
				'smtp_server' => 'mail.example.com',
				'smtp_helo' => 'example.com',
				'smtp_email' => 'zabbix@example.com',
				'status' => MEDIA_TYPE_STATUS_ACTIVE,
				'parameters' => []
			] + $defaults,
			[
				'name' => 'Script without parameters',
				'type' => (string) CXmlConstantValue::MEDIA_TYPE_SCRIPT,
				'exec_path' => 'script.sh',
				'status' => MEDIA_TYPE_STATUS_ACTIVE,
				'parameters' => []
			] + $defaults,
			[
				'name' => 'Script with parameters',
				'type' => (string) CXmlConstantValue::MEDIA_TYPE_SCRIPT,
				'exec_path' => 'script.sh',
				'status' => MEDIA_TYPE_STATUS_ACTIVE,
				'parameters' => [
					['sortorder' => '0', 'value' => 100],
					['sortorder' => '1', 'value' => 200],
					['sortorder' => '2', 'value' => 300]
				]
			] + $defaults,
			[
				'name' => 'SMS',
				'type' => (string) CXmlConstantValue::MEDIA_TYPE_SMS,
				'gsm_modem' => '/dev/ttyS0',
				'parameters' => [],
				'status' => MEDIA_TYPE_STATUS_ACTIVE
			] + $defaults,
			[
				'name' => 'Webhook without parameters',
				'type' => (string) CXmlConstantValue::MEDIA_TYPE_WEBHOOK,
				'parameters' => [],
				'script' => 'return true;',
				'status' => MEDIA_TYPE_STATUS_ACTIVE
			] + $defaults,
			[
				'name' => 'Webhook with parameters',
				'type' => (string) CXmlConstantValue::MEDIA_TYPE_WEBHOOK,
				'parameters' => [
					[
						'name' => 'URL',
						'value' => ''
					],
					[
						'name' => 'To',
						'value' => '{ALERT.SENDTO}'
					],
					[
						'name' => 'Subject',
						'value' => '{ALERT.SUBJECT}'
					],
					[
						'name' => 'Message',
						'value' => '{ALERT.MESSAGE}'
					]
				],
				'script' => 'return true;',
				'status' => MEDIA_TYPE_STATUS_ACTIVE
			] + $defaults
		], $adapter->getMediaTypes());
	}

	public function testConversion() {
		$adapter = $this->getAdapter($this->get18Xml());

		$this->assertEquals([
			[
				'uuid' => 'dc579cd7a1a34222933f24f52a68bcd8',
				'name' => 'Linux servers'
			]
		], $adapter->getHostGroups());

		$this->assertEquals([
			[
				'uuid' => '7df96b18c230490a9a0a9e2307226338',
				'name' => 'Templates'
			]
		], $adapter->getTemplateGroups());

		$this->assertEquals([
			[
				'macros' => [],
				'interfaces' => [
					[
						'type' => '1',
						'useip' => '1',
						'ip' => '10.0.0.6',
						'dns' => 'localhost',
						'port' => '10050',
						'interface_ref' => 'if0',
						'details' => [],
						'main' => '1'
					]
				],
				'host' => 'host',
				'status' => '0',
				'ipmi_authtype' => '0',
				'ipmi_privilege' => '2',
				'ipmi_username' => '',
				'ipmi_password' => '',
				'inventory_mode' => '-1',
				'inventory' => [],
				'groups' =>	[
					[
						'name' => 'Linux servers'
					]
				],
				'templates' => [],
				'monitored_by' => '0',
				'proxy' => [],
				'proxy_group' => [],
				'description' => '',
				'name' => 'host',
				'tags' => [],
				'valuemaps' => []
			]
		], $adapter->getHosts());

		$this->assertEquals([
			[
				'uuid' => '0f5ffb0773844d77b8a8622f7819ccdf',
				'macros' => [
					[
						'value' => '21',
						'macro' => '{$PORT.FTP}',
						'type' => '0',
						'description' => ''
					],
					[
						'value' => '22',
						'macro' => '{$PORT.SSH}',
						'type' => '0',
						'description' => ''
					]
				],
				'host' => 'Template_Linux',
				'groups' =>	[
					[
						'name' => 'Templates'
					]
				],
				'templates' => [],
				'name' => 'Template_Linux',
				'description' => '',
				'vendor_name' => '',
				'vendor_version' => '',
				'tags' => [],
				'valuemaps' => []
			],
			[
				'uuid' => 'a038cce155ec42a4a85d6fea05632ed1',
				'macros' => [],
				'host' => 'Template_Simple',
				'groups' =>	[
					[
						'name' => 'Templates'
					]
				],
				'templates' => [],
				'name' => 'Template_Simple',
				'description' => '',
				'vendor_name' => '',
				'vendor_version' => '',
				'tags' => [],
				'valuemaps' => []
			]
		], $adapter->getTemplates());

		$this->assertEquals([
			'Template_Linux' => [
				'vfs.fs.size[/,pfree]' => [
					'uuid' => '1af0599983904849aed77e1bc145a8c2',
					'type' => (string) ITEM_TYPE_ZABBIX,
					'value_type' => '0',
					'delay' => '30',
					'history' => '7d',
					'trends' => '365d',
					'status' => '0',
					'units' => '%',
					'tags' => [
						[
							'tag' => 'Application',
							'value' => 'Filesystem'
						],
						[
							'tag' => 'Application',
							'value' => 'Availability'
						]
					],
					'name' => 'Free disk space on / in %',
					'key_' => 'vfs.fs.size[/,pfree]',
					'triggers' => [],
					'description' => 'Free disk space on / in %',
					'inventory_link' => '0',
					'preprocessing' => [],
					'timeout' => '',
					'valuemap' => []
				]
			],
			'Template_Simple' => [
				'net.tcp.service[ftp,,21]' => [
					'uuid' => 'c1e7021d16814cde8d17c783a987bb18',
					'type' => (string) ITEM_TYPE_SIMPLE,
					'value_type' => '3',
					'delay' => '30',
					'history' => '90d',
					'trends' => '365d',
					'status' => '0',
					'units' => '',
					'username' => '',
					'password' => '',
					'tags' => [
						[
							'tag' => 'Application',
							'value' => 'Simple checks'
						]
					],
					'name' => 'FTP check',
					'key_' => 'net.tcp.service[ftp,,21]',
					'triggers' => [],
					'description' => 'FTP check',
					'inventory_link' => '0',
					'preprocessing' => [],
					'timeout' => '',
					'valuemap' => []
				],
				'net.tcp.service[ftp,,{$PORT.FTP}]' => [
					'uuid' => '37c5c2d56a1c49ecaa7d6d0f70eb8a35',
					'type' => (string) ITEM_TYPE_SIMPLE,
					'value_type' => '3',
					'delay' => '30',
					'history' => '90d',
					'trends' => '365d',
					'status' => '0',
					'units' => '',
					'username' => '',
					'password' => '',
					'tags' => [
						[
							'tag' => 'Application',
							'value' => 'Simple checks'
						]
					],
					'name' => 'FTP check with macro',
					'key_' => 'net.tcp.service[ftp,,{$PORT.FTP}]',
					'triggers' => [],
					'description' => 'FTP check with macro',
					'inventory_link' => '0',
					'preprocessing' => [],
					'timeout' => '',
					'valuemap' => []
				]
			]
		], $adapter->getItems());

		$this->assertEquals([
			[
				'uuid' => '4b481ada990d4511894db8f49239c611',
				'type' => '0',
				'expression' => 'last(/Template_Linux/vfs.fs.size[/,pfree])<10',
				'url' => 'http://www.zabbix.com/',
				'status' => '0',
				'priority' => '4',
				'comments' => 'test comments',
				'description' => 'Low free disk space on {HOSTNAME} volume /',
				'recovery_mode' => (string) ZBX_RECOVERY_MODE_EXPRESSION,
				'recovery_expression' => '',
				'correlation_mode' => (string) ZBX_TRIGGER_CORRELATION_NONE,
				'correlation_tag' => '',
				'event_name' => '',
				'opdata' => '',
				'url_name' => '',
				'tags' => [],
				'manual_close' => (string) ZBX_TRIGGER_MANUAL_CLOSE_NOT_ALLOWED,
				'dependencies' => []
			],
			[
				'uuid' => '37d8550be8a64440a265004dfdad0a4a',
				'type' => '1',
				'expression' => 'last(/Template_Simple/net.tcp.service[ftp,,21])<>0 or last(/Template_Simple/net.tcp.service[ftp,,{$PORT.FTP}])<>0',
				'url' => 'triggers.php',
				'status' => '1',
				'priority' => '3',
				'comments' => 'comments',
				'description' => 'simple triggert',
				'correlation_mode' => (string) ZBX_TRIGGER_CORRELATION_NONE,
				'recovery_mode' => (string) ZBX_RECOVERY_MODE_EXPRESSION,
				'recovery_expression' => '',
				'correlation_tag' => '',
				'event_name' => '',
				'opdata' => '',
				'url_name' => '',
				'tags' => [],
				'manual_close' => (string) ZBX_TRIGGER_MANUAL_CLOSE_NOT_ALLOWED,
				'dependencies' => []
			]
		], $adapter->getTriggers());

		$this->assertEquals([
			[
				'uuid' => '0b0dcd48bc5248f0a5fd0bb62ab7ee94',
				'name' => 'simple graph fixed',
				'width' => '755',
				'height' => '332',
				'ymin_type' => '1',
				'ymax_type' => '1',
				'show_work_period' => '1',
				'show_triggers' => '1',
				'yaxismin' => '5.5000',
				'yaxismax' => '95.6000',
				'show_3d' => '0',
				'percent_left' => '25.5000',
				'percent_right' => '27.6000',
				'ymin_item_1' => '0',
				'ymax_item_1' => '0',
				'graphtype' => '0',
				'gitems' => [
					[
						'item' => [
							'host' => 'Template_Simple',
							'key' => 'net.tcp.service[ftp,,21]'
						],
						'drawtype' => '0',
						'sortorder' => '0',
						'color' => '3333FF',
						'yaxisside' => '0',
						'calc_fnc' => '7',
						'type' => '0'
					],
					[
						'item' => [
							'host' => 'Template_Simple',
							'key' => 'net.tcp.service[ftp,,{$PORT.FTP}]'
						],
						'drawtype' => '1',
						'sortorder' => '1',
						'color' => '009999',
						'yaxisside' => '1',
						'calc_fnc' => '4',
						'type' => '0'
					]
				],
				'show_legend' => '0'
			],
			[
				'uuid' => '7f147b35d45646e59bc973b21adaac6b',
				'name' => 'simple graph',
				'width' => '900',
				'height' => '200',
				'ymin_type' => '0',
				'ymax_type' => '0',
				'show_work_period' => '0',
				'show_triggers' => '0',
				'yaxismin' => '0.0000',
				'yaxismax' => '100.0000',
				'show_3d' => '0',
				'percent_left' => '0.0000',
				'percent_right' => '0.0000',
				'ymin_item_1' => '0',
				'ymax_item_1' => '0',
				'graphtype' => '0',
				'gitems' => [
					[
						'item' => [
							'host' => 'Template_Simple',
							'key' => 'net.tcp.service[ftp,,21]'
						],
						'drawtype' => '0',
						'sortorder' => '0',
						'color' => '3333FF',
						'yaxisside' => '0',
						'calc_fnc' => '2',
						'type' => '0'
					],
					[
						'item' => [
							'host' => 'Template_Simple',
							'key' => 'net.tcp.service[ftp,,{$PORT.FTP}]'
						],
						'drawtype' => '0',
						'sortorder' => '1',
						'color' => '009999',
						'yaxisside' => '0',
						'calc_fnc' => '2',
						'type' => '0'
					]
				],
				'show_legend' => '0'
			],
			[
				'uuid' => '733df972eb904450bc90c63c13fcf6f6',
				'name' => 'simple graph min/max',
				'width' => '1024',
				'height' => '768',
				'ymin_type' => '2',
				'ymax_type' => '2',
				'show_work_period' => '1',
				'show_triggers' => '1',
				'yaxismin' => '0.0000',
				'yaxismax' => '0.0000',
				'show_3d' => '0',
				'percent_left' => '0.0000',
				'percent_right' => '0.0000',
				'ymin_item_1' => [
					'host' => 'Template_Simple',
					'key' => 'net.tcp.service[ftp,,21]'
				],
				'ymax_item_1' => [
					'host' => 'Template_Simple',
					'key' => 'net.tcp.service[ftp,,{$PORT.FTP}]'
				],
				'graphtype' => '1',
				'gitems' => [
					[
						'item' => [
							'host' => 'Template_Simple',
							'key' => 'net.tcp.service[ftp,,21]'
						],
						'drawtype' => '0',
						'sortorder' => '0',
						'color' => '3333FF',
						'yaxisside' => '0',
						'calc_fnc' => '2',
						'type' => '0'
					],
					[
						'item' => [
							'host' => 'Template_Simple',
							'key' => 'net.tcp.service[ftp,,{$PORT.FTP}]'
						],
						'drawtype' => '0',
						'sortorder' => '1',
						'color' => '009999',
						'yaxisside' => '0',
						'calc_fnc' => '2',
						'type' => '0'
					]
				],
				'show_legend' => '0'
			]
		], $adapter->getGraphs());
	}

	public function testUnsupportedVersion() {
		$xml = '<?xml version="1.0" encoding="UTF-8"?>
			<zabbix_export>
				<version>0.1</version>
				<date>2014-11-14T09:41:02Z</date>
			</zabbix_export>';

		//$this->expectException('Exception', 'Invalid tag "/zabbix_export/version": unsupported version number.');
		$this->expectException(Exception::class);
		$this->expectExceptionMessage('Invalid tag "/zabbix_export/version": unsupported version number.');
		$this->getAdapter($xml);
	}

	public function test10SchemaTransformationToLatest() {
		$adapter = $this->getAdapter($this->get10Xml());

		$this->assertEquals([
			[
				'name' => 'host',
				'status' => '0',
				'ipmi_authtype' => '0',
				'ipmi_privilege' => '2',
				'groups' => [
					[
						'name' => 'Linux servers'
					]
				],
				'templates' => [],
				'host' => 'host',
				'interfaces' =>
				[
					[
						'type' => '1',
						'useip' => '1',
						'ip' => '10.0.0.6',
						'dns' => 'localhost',
						'port' => '10050',
						'main' => '1',
						'interface_ref' => 'if0',
						'details' => []
					]
				],
				'monitored_by' => '0',
				'proxy' => [],
				'proxy_group' => [],
				'inventory_mode' => '-1',
				'description' => '',
				'inventory' => [],
				'ipmi_password' => '',
				'ipmi_username' => '',
				'macros' => [],
				'tags' => [],
				'valuemaps' => []
			]
		], $adapter->getHosts());

		$this->assertEquals([
			[
				'groups' => [
					[
						'name' => 'Templates'
					]
				],
				'macros' => [
					[
						'value' => '23',
						'macro' => '{#VALUE}',
						'type' => '0',
						'description' => ''
					]
				],
				'templates' => [
					[
						'name' => 'template'
					]
				],
				'uuid' => 'a038cce155ec42a4a85d6fea05632ed1',
				'host' => 'Template_Simple',
				'name' => 'Template_Simple',
				'description' => '',
				'vendor_name' => '',
				'vendor_version' => '',
				'tags' => [],
				'valuemaps' => []
			]
		], $adapter->getTemplates());

		$this->assertEquals([
			'Template_Simple' => [
				'net.tcp.service[ftp,,21]' => [
					'uuid' => 'c1e7021d16814cde8d17c783a987bb18',
					'type' => (string) ITEM_TYPE_SIMPLE,
					'value_type' => '3',
					'description' => 'FTP check',
					'delay' => '30',
					'history' => '90d',
					'trends' => '365d',
					'status' => '0',
					'tags' => [
						[
							'tag' => 'Application',
							'value' => 'Simple checks'
						]
					],
					'name' => 'FTP check',
					'inventory_link' => '0',
					'password' => '',
					'preprocessing' => [],
					'timeout' => '',
					'triggers' => [],
					'units' => '',
					'username' => '',
					'valuemap' => [],
					'key_' => 'net.tcp.service[ftp,,21]'
				],
				'net.tcp.service[ftp,,{$PORT.FTP}]' => [
					'uuid' => '37c5c2d56a1c49ecaa7d6d0f70eb8a35',
					'type' => (string) ITEM_TYPE_SIMPLE,
					'value_type' => '3',
					'description' => 'FTP check with macro',
					'delay' => '30',
					'history' => '90d',
					'trends' => '365d',
					'status' => '0',
					'timeout' => '',
					'tags' => [
						[
							'tag' => 'Application',
							'value' => 'Simple checks'
						]
					],
					'name' => 'FTP check with macro',
					'inventory_link' => '0',
					'password' => '',
					'preprocessing' => [],
					'triggers' => [],
					'units' => '',
					'username' => '',
					'valuemap' => [],
					'key_' => 'net.tcp.service[ftp,,{$PORT.FTP}]'
				]
			]
		], $adapter->getItems());
	}

	public function testConstantConverter() {
		$schema = ['type' => XML_ARRAY, 'rules' => [
			'constants' => ['type' => XML_INDEXED_ARRAY, 'prefix' => 'constant', 'rules' => [
				'constant' => ['type' => XML_ARRAY, 'rules' => [
					'first' => ['type' => XML_STRING, 'in' => [0 => 'ZERO', 1 => 'FIRST']],
					'second' => ['type' => XML_STRING, 'ex_rules' => [$this, 'constantConverterExRules']],
					'third' => ['type' => XML_STRING]
				]]
			]]
		]];
		$source = [
			'zabbix_export' => [
				'constants' => [
					'constant' => [
						'first' => 'FIRST',
						'second' => 'SECOND',
						'third' => 'test'
					]
				]
			]
		];
		$source = (new CConstantImportConverter($schema))->convert($source);

		$this->assertEquals([
			'zabbix_export' => [
				'constants' => [
					'constant' => [
						'first' => '1',
						'second' => '2',
						'third' => 'test'
					]
				]
			]
		], $source);
	}

	public function constantConverterExRules(array $data) {
		return ['type' => XML_STRING, 'in' => [0 => 'ZERO', 1 => 'FIRST', 2 => 'SECOND']];
	}

	public function testConstantConverterValueError() {
		$this->expectException(Exception::class);
		$this->expectExceptionMessage('Invalid tag "first": unexpected constant value "1".');

		$schema = ['type' => XML_ARRAY, 'rules' => [
			'constants' => ['type' => XML_INDEXED_ARRAY, 'prefix' => 'constant', 'rules' => [
				'constant' => ['type' => XML_ARRAY, 'rules' => [
					'first' => ['type' => XML_STRING, 'in' => ['0' => 'ZERO']]
				]]
			]]
		]];
		$source = [
			'zabbix_export' => [
				'constants' => [
					'constant' => [
						'first' => '1'
					]
				]
			]
		];
		$source = (new CConstantImportConverter($schema))->convert($source);
	}

	public function testDefaultValueConverter() {
		$schema = ['type' => XML_ARRAY, 'rules' => [
			'default_values' => ['type' => XML_INDEXED_ARRAY, 'prefix' => 'values', 'rules' => [
				'values' => ['type' => XML_ARRAY, 'rules' => [
					'var0' => ['type' => XML_STRING, 'default' => 1],
					'var1' => ['type' => XML_STRING, 'default' => 1],
					'var2' => ['type' => XML_STRING],
					'var3' => ['type' => XML_ARRAY, 'rules' => [
						'subvar1' => ['type' => XML_STRING, 'default' => 'array']
					]],
					'var4' => ['type' => XML_ARRAY, 'rules' => [
						'subvar1' => ['type' => XML_STRING, 'default' => 'array']
					]]
				]]
			]]
		]];
		$source = [
			'zabbix_export' => [
				'default_values' => [
					'values' => [
						'var0' => 'test',
						'var4' => []
					]
				]
			]
		];
		$source = (new CDefaultImportConverter($schema))->convert($source);

		$this->assertEquals([
			'zabbix_export' => [
				'default_values' => [
					'values' => [
						'var0' => 'test',
						'var1' => '1',
						'var2' => '',
						'var3' => [],
						'var4' => [
							'subvar1' => 'array'
						]
					]
				]
			]
		], $source);
	}

	public function testArrayKeysConverter() {
		$schema = ['type' => XML_ARRAY, 'rules' => [
			'tests' => ['type' => XML_INDEXED_ARRAY, 'prefix' => 'test', 'rules' => [
				'test' => ['type' => XML_ARRAY, 'rules' => [
					'value' => ['type' => XML_STRING],
					'values' => ['type' => XML_INDEXED_ARRAY, 'prefix' => 'value', 'rules' => [
						'value' => ['type' => XML_ARRAY, 'rules' => [
							'host' => ['type' => XML_STRING]
						]]
					]]
				]]
			]]
		]];
		$source = [
			'zabbix_export' => [
				'tests' => [
					'test' => [
						'values' => [
							'value' => [
								'host' => ''
							],
							'value2' => [
								'host' => ''
							],
							'value3' => [
								'host' => ''
							]
						]
					],
					'test2' => [
						'value' => ''
					],
					'test3' => [
						'values' => [
							'value' => [
								'host' => ''
							],
							'value2' => [
								'host' => ''
							],
							'value3' => [
								'host' => ''
							]
						]
					]
				]
			]
		];
		$source = (new CImportDataNormalizer($schema))->normalize($source);

		$this->assertEquals([
			'zabbix_export' => [
				'tests' => [
					[
						'values' => [
							[
								'host' => ''
							],
							[
								'host' => ''
							],
							[
								'host' => ''
							]
						]
					],
					[
						'value' => ''
					],
					[
						'values' => [
							[
								'host' => ''
							],
							[
								'host' => ''
							],
							[
								'host' => ''
							]
						]
					]
				]
			]
		], $source);
	}

	public function testTemplateSnmpConverter() {
		$adapter = $this->getAdapter($this->getSNMPTemplateXml());

		$this->assertEquals([
			[
				'groups' => [
					[
						'name' => 'Templates'
					]
				],
				'macros' => [],
				'templates' => [],
				'uuid' => '206a9b642b3e46c89a61696ab28f3d5c',
				'host' => 'Test 1',
				'name' => 'Test 1',
				'description' => '',
				'vendor_name' => '',
				'vendor_version' => '',
				'tags' => [],
				'valuemaps' => []
			]
		], $adapter->getTemplates());

		$this->assertEquals([
			'Test 1' => [
				'test' => [
					'uuid' => '86491ebd3d2549eaab7bbba6537c5e9b',
					'name' => 'Item SNMPv1 without port',
					'type' => '20',
					'snmp_oid' => 'test',
					'delay' => '1m',
					'history' => '90d',
					'trends' => '365d',
					'status' => '0',
					'value_type' => '3',
					'units' => '',
					'description' => '',
					'inventory_link' => '0',
					'tags' => [],
					'valuemap' => [],
					'preprocessing' => [],
					'timeout' => '',
					'triggers' => [],
					'key_' => 'test'
				],
				'test2' => [
					'uuid' => 'c036b6c02dc14b61b981842081a3887d',
					'name' => 'Item SNMPv1 with port',
					'type' => '20',
					'snmp_oid' => 'test',
					'delay' => '1m',
					'history' => '90d',
					'trends' => '365d',
					'status' => '0',
					'value_type' => '3',
					'units' => '',
					'description' => '',
					'inventory_link' => '0',
					'tags' => [],
					'valuemap' => [],
					'preprocessing' => [],
					'timeout' => '',
					'triggers' => [],
					'key_' => 'test2'
				],
				'test3' => [
					'uuid' => 'a7ffc1b7cf88455c89ef04284fcc9f4e',
					'name' => 'Item SNMPv2 without port',
					'type' => '20',
					'snmp_oid' => 'test',
					'delay' => '1m',
					'history' => '90d',
					'trends' => '365d',
					'status' => '0',
					'value_type' => '3',
					'units' => '',
					'description' => '',
					'inventory_link' => '0',
					'tags' => [],
					'valuemap' => [],
					'preprocessing' => [],
					'timeout' => '',
					'triggers' => [],
					'key_' => 'test3'
				],
				'test4' => [
					'uuid' => 'e678a548f5194961b8b3cd20214bd7fa',
					'name' => 'Item SNMPv2 with port',
					'type' => '20',
					'snmp_oid' => 'test',
					'delay' => '1m',
					'history' => '90d',
					'trends' => '365d',
					'status' => '0',
					'value_type' => '3',
					'units' => '',
					'description' => '',
					'inventory_link' => '0',
					'tags' => [],
					'valuemap' => [],
					'preprocessing' => [],
					'timeout' => '',
					'triggers' => [],
					'key_' => 'test4'
				],
				'test5' => [
					'uuid' => '72be963b76ed41fea8577b83fcc279bf',
					'name' => 'Item SNMPv3 without port',
					'type' => '20',
					'snmp_oid' => 'test',
					'delay' => '1m',
					'history' => '90d',
					'trends' => '365d',
					'status' => '0',
					'value_type' => '3',
					'units' => '',
					'description' => '',
					'inventory_link' => '0',
					'tags' => [],
					'valuemap' => [],
					'preprocessing' => [],
					'timeout' => '',
					'triggers' => [],
					'key_' => 'test5'
				],
				'test6' => [
					'uuid' => 'a0891fa71e2b45dba8587c29cd137a09',
					'name' => 'Item SNMPv3 with port',
					'type' => '20',
					'snmp_oid' => 'test',
					'delay' => '1m',
					'history' => '90d',
					'trends' => '365d',
					'status' => '0',
					'value_type' => '3',
					'units' => '',
					'description' => '',
					'inventory_link' => '0',
					'tags' => [],
					'valuemap' => [],
					'preprocessing' => [],
					'timeout' => '',
					'triggers' => [],
					'key_' => 'test6'
				]
			]
		], $adapter->getItems());

		$this->assertEquals([
			'Test 1' => [
				'drule' => [
					'uuid' => '3b7d292c10354838805205cfcbc444cc',
					'name' => 'Discovery Rule 1',
					'type' => '20',
					'snmp_oid' => 'test',
					'item_prototypes' => [
						[
							'uuid' => '779884b6c977492e87fbda06daa13756',
							'name' => 'Drule Item SNMP v1',
							'type' => '20',
							'snmp_oid' => 'test',
							'delay' => '1m',
							'history' => '31d',
							'trends' => '365d',
							'status' => '0',
							'discover' => '0',
							'value_type' => '3',
							'units' => '',
							'description' => '',
							'tags' => [],
							'valuemap' => [],
							'preprocessing' => [],
							'timeout' => '',
							'key_' => 'test7',
							'trigger_prototypes' => []
						]
					],
					'filter' => [
						'conditions' => [],
						'evaltype' => (string) CONDITION_EVAL_TYPE_AND_OR
					],
					'delay' => '1m',
					'status' => '0',
					'lifetime' => '30d',
					'description' => '',
					'trigger_prototypes' => [],
					'graph_prototypes' => [],
					'host_prototypes' => [],
					'lifetime_type' => (string) ZBX_LLD_DELETE_AFTER,
					'enabled_lifetime_type' => (string) ZBX_LLD_DELETE_NEVER,
					'lld_macro_paths' => [],
					'preprocessing' => [],
					'timeout' => '',
					'overrides' => [],
					'key_' => 'drule'
				],
				'drule2' => [
					'uuid' => '72eebc5b22a340f084a53ae0aa0be7c9',
					'name' => 'Discovery Rule 2',
					'type' => '20',
					'snmp_oid' => 'test',
					'item_prototypes' => [
						[
							'uuid' => '1ce99b4e607f4b1381207b9952f59b2b',
							'name' => 'Drule Item SNMP v2',
							'type' => '20',
							'snmp_oid' => 'test',
							'delay' => '1m',
							'history' => '31d',
							'trends' => '365d',
							'status' => '0',
							'discover' => '0',
							'value_type' => '3',
							'units' => '',
							'description' => '',
							'tags' => [],
							'valuemap' => [],
							'preprocessing' => [],
							'timeout' => '',
							'key_' => 'test8',
							'trigger_prototypes' => []
						]
					],
					'filter' => [
						'conditions' => [],
						'evaltype' => (string) CONDITION_EVAL_TYPE_AND_OR
					],
					'delay' => '1m',
					'status' => '0',
					'lifetime' => '30d',
					'description' => '',
					'trigger_prototypes' => [],
					'graph_prototypes' => [],
					'host_prototypes' => [],
					'lifetime_type' => (string) ZBX_LLD_DELETE_AFTER,
					'enabled_lifetime_type' => (string) ZBX_LLD_DELETE_NEVER,
					'lld_macro_paths' => [],
					'preprocessing' => [],
					'timeout' => '',
					'overrides' => [],
					'key_' => 'drule2'
				],
				'drule3' => [
					'uuid' => '857400f45ff845de8ee70e132299bd4e',
					'name' => 'Discovery Rule 3',
					'type' => '20',
					'snmp_oid' => 'test',
					'item_prototypes' => [
						[
							'uuid' => 'b178dc2e1e234031bdbd46007542ffcc',
							'name' => 'Drule Item SNMP v3',
							'type' => '20',
							'snmp_oid' => 'test',
							'delay' => '1m',
							'history' => '31d',
							'trends' => '365d',
							'status' => '0',
							'discover' => '0',
							'value_type' => '3',
							'units' => '',
							'description' => '',
							'tags' => [],
							'valuemap' => [],
							'preprocessing' => [],
							'timeout' => '',
							'key_' => 'test9',
							'trigger_prototypes' => []
						]
					],
					'filter' => [
						'conditions' => [],
						'evaltype' => (string) CONDITION_EVAL_TYPE_AND_OR
					],
					'delay' => '1m',
					'status' => '0',
					'lifetime' => '30d',
					'description' => '',
					'trigger_prototypes' => [],
					'graph_prototypes' => [],
					'host_prototypes' => [],
					'lifetime_type' => (string) ZBX_LLD_DELETE_AFTER,
					'enabled_lifetime_type' => (string) ZBX_LLD_DELETE_NEVER,
					'lld_macro_paths' => [],
					'preprocessing' => [],
					'timeout' => '',
					'overrides' => [],
					'key_' => 'drule3'
				]
			]
		], $adapter->getDiscoveryRules());
	}

	public function testHostSnmpConverter() {
		$adapter = $this->getAdapter($this->getSNMPHostXml());

		$this->assertEquals([
			[
				'inventory' => [],
				'monitored_by' => '0',
				'proxy' => [],
				'proxy_group' => [],
				'groups' => [
					[
						'name' => 'Templates'
					]
				],
				'templates' => [],
				'macros' => [],
				'interfaces' => [
					[
						'interface_ref' => 'if1',
						'type' => '1',
						'useip' => '1',
						'ip' => '127.0.0.1',
						'dns' => '',
						'port' => '10050',
						'details' => [],
						'main' => '1'
					],
					[
						'interface_ref' => 'if3',
						'type' => '2',
						'port' => '161',
						'details' => [
							'bulk' => '1',
							'version' => '1',
							'community' => 'public',
							'max_repetitions' => '10',
							'contextname' => '',
							'securityname' => '',
							'securitylevel' => '0',
							'authprotocol' => '0',
							'authpassphrase' => '',
							'privprotocol' => '0',
							'privpassphrase' => ''
						],
						'useip' => '1',
						'ip' => '127.0.0.1',
						'dns' => '',
						'main' => '1'
					],
					[
						'interface_ref' => 'if4',
						'type' => '2',
						'port' => '162',
						'details' => [
							'bulk' => '1',
							'version' => '1',
							'community' => 'public',
							'max_repetitions' => '10',
							'contextname' => '',
							'securityname' => '',
							'securitylevel' => '0',
							'authprotocol' => '0',
							'authpassphrase' => '',
							'privprotocol' => '0',
							'privpassphrase' => ''
						],
						'useip' => '1',
						'ip' => '127.0.0.1',
						'dns' => '',
						'main' => '0'
					],
					[
						'interface_ref' => 'if5',
						'type' => '2',
						'port' => '161',
						'details' => [
							'bulk' => '1',
							'version' => '2',
							'community' => 'public',
							'max_repetitions' => '10',
							'contextname' => '',
							'securityname' => '',
							'securitylevel' => '0',
							'authprotocol' => '0',
							'authpassphrase' => '',
							'privprotocol' => '0',
							'privpassphrase' => ''
						],
						'useip' => '1',
						'ip' => '127.0.0.1',
						'dns' => '',
						'main' => '0'
					],
					[
						'interface_ref' => 'if6',
						'type' => '2',
						'port' => '163',
						'details' => [
							'bulk' => '1',
							'version' => '2',
							'community' => 'public',
							'max_repetitions' => '10',
							'contextname' => '',
							'securityname' => '',
							'securitylevel' => '0',
							'authprotocol' => '0',
							'authpassphrase' => '',
							'privprotocol' => '0',
							'privpassphrase' => ''
						],
						'useip' => '1',
						'ip' => '127.0.0.1',
						'dns' => '',
						'main' => '0'
					],
					[
						'interface_ref' => 'if7',
						'type' => '2',
						'port' => '161',
						'details' => [
							'bulk' => '1',
							'version' => '3',
							'contextname' => 'test',
							'securityname' => 'test',
							'securitylevel' => '2',
							'authprotocol' => '0',
							'authpassphrase' => 'test',
							'privprotocol' => '0',
							'privpassphrase' => 'test',
							'community' => '',
							'max_repetitions' => '10'
						],
						'useip' => '1',
						'ip' => '127.0.0.1',
						'dns' => '',
						'main' => '0'
					],
					[
						'interface_ref' => 'if8',
						'type' => '2',
						'port' => '164',
						'details' => [
							'bulk' => '1',
							'version' => '3',
							'contextname' => 'test',
							'securityname' => 'test',
							'securitylevel' => '2',
							'authprotocol' => '0',
							'authpassphrase' => 'test',
							'privprotocol' => '0',
							'privpassphrase' => 'test',
							'community' => '',
							'max_repetitions' => '10'
						],
						'useip' => '1',
						'ip' => '127.0.0.1',
						'dns' => '',
						'main' => '0'
					],
					[
						'interface_ref' => 'if9',
						'type' => '2',
						'port' => '161',
						'details' => [
							'bulk' => '1',
							'version' => '3',
							'contextname' => 'test',
							'securityname' => 'test',
							'securitylevel' => '2',
							'authprotocol' => '1',
							'authpassphrase' => 'test',
							'privprotocol' => '0',
							'privpassphrase' => 'test',
							'community' => '',
							'max_repetitions' => '10'
						],
						'useip' => '1',
						'ip' => '127.0.0.1',
						'dns' => '',
						'main' => '0'
					]
				],
				'host' => 'SNMP host',
				'status' => '0',
				'description' => '',
				'ipmi_authtype' => '-1',
				'ipmi_privilege' => '2',
				'ipmi_username' => '',
				'ipmi_password' => '',
				'name' => 'SNMP host',
				'inventory_mode' => '-1',
				'tags' => [],
				'valuemaps' => []
			]
		], $adapter->getHosts());

		$this->assertEquals([
			'SNMP host' => [
				'test' => [
					'name' => 'Item SNMPv1 without port',
					'type' => '20',
					'snmp_oid' => 'test',
					'interface_ref' => 'if3',
					'delay' => '1m',
					'history' => '90d',
					'trends' => '365d',
					'status' => '0',
					'value_type' => '3',
					'units' => '',
					'description' => '',
					'inventory_link' => '0',
					'tags' => [],
					'valuemap' => [],
					'preprocessing' => [],
					'timeout' => '',
					'triggers' => [],
					'key_' => 'test'
				],
				'test2' => [
					'name' => 'Item SNMPv1 with port',
					'type' => '20',
					'snmp_oid' => 'test',
					'interface_ref' => 'if4',
					'delay' => '1m',
					'history' => '90d',
					'trends' => '365d',
					'status' => '0',
					'value_type' => '3',
					'units' => '',
					'description' => '',
					'inventory_link' => '0',
					'tags' => [],
					'valuemap' => [],
					'preprocessing' => [],
					'timeout' => '',
					'triggers' => [],
					'key_' => 'test2'
				],
				'test3' => [
					'name' => 'Item SNMPv2 without port',
					'type' => '20',
					'snmp_oid' => 'test',
					'interface_ref' => 'if5',
					'delay' => '1m',
					'history' => '90d',
					'trends' => '365d',
					'status' => '0',
					'value_type' => '3',
					'units' => '',
					'description' => '',
					'inventory_link' => '0',
					'tags' => [],
					'valuemap' => [],
					'preprocessing' => [],
					'timeout' => '',
					'triggers' => [],
					'key_' => 'test3'
				],
				'test4' => [
					'name' => 'Item SNMPv2 with port',
					'type' => '20',
					'snmp_oid' => 'test',
					'interface_ref' => 'if6',
					'delay' => '1m',
					'history' => '90d',
					'trends' => '365d',
					'status' => '0',
					'value_type' => '3',
					'units' => '',
					'description' => '',
					'inventory_link' => '0',
					'tags' => [],
					'valuemap' => [],
					'preprocessing' => [],
					'timeout' => '',
					'triggers' => [],
					'key_' => 'test4'
				],
				'test5' => [
					'name' => 'Item SNMPv3 without port',
					'type' => '20',
					'snmp_oid' => 'test',
					'interface_ref' => 'if7',
					'delay' => '1m',
					'history' => '90d',
					'trends' => '365d',
					'status' => '0',
					'value_type' => '3',
					'units' => '',
					'description' => '',
					'inventory_link' => '0',
					'tags' => [],
					'valuemap' => [],
					'preprocessing' => [],
					'timeout' => '',
					'triggers' => [],
					'key_' => 'test5'
				],
				'test6' => [
					'name' => 'Item SNMPv3 with port',
					'type' => '20',
					'snmp_oid' => 'test',
					'interface_ref' => 'if8',
					'delay' => '1m',
					'history' => '90d',
					'trends' => '365d',
					'status' => '0',
					'value_type' => '3',
					'units' => '',
					'description' => '',
					'inventory_link' => '0',
					'tags' => [],
					'valuemap' => [],
					'preprocessing' => [],
					'timeout' => '',
					'triggers' => [],
					'key_' => 'test6'
				]
			]
		], $adapter->getItems());

		$this->assertEquals([
			'SNMP host' => [
				'drule' => [
					'name' => 'Discovery Rule 1',
					'type' => '20',
					'snmp_oid' => 'test',
					'interface_ref' => 'if3',
					'item_prototypes' => [
						[
							'name' => 'Drule Item SNMP v1',
							'type' => '20',
							'snmp_oid' => 'test',
							'interface_ref' => 'if3',
							'delay' => '1m',
							'history' => '31d',
							'trends' => '365d',
							'status' => '0',
							'discover' => '0',
							'value_type' => '3',
							'units' => '',
							'description' => '',
							'tags' => [],
							'valuemap' => [],
							'preprocessing' => [],
							'timeout' => '',
							'key_' => 'test7',
							'trigger_prototypes' => []
						]
					],
					'filter' => [
						'conditions' => [],
						'evaltype' => (string) CONDITION_EVAL_TYPE_AND_OR
					],
					'delay' => '1m',
					'status' => '0',
					'lifetime' => '30d',
					'description' => '',
					'trigger_prototypes' => [],
					'graph_prototypes' => [],
					'host_prototypes' => [],
					'lifetime_type' => (string) ZBX_LLD_DELETE_AFTER,
					'enabled_lifetime_type' => (string) ZBX_LLD_DELETE_NEVER,
					'lld_macro_paths' => [],
					'preprocessing' => [],
					'timeout' => '',
					'overrides' => [],
					'key_' => 'drule'
				],
				'drule2' => [
					'name' => 'Discovery Rule 2',
					'type' => '20',
					'snmp_oid' => 'test',
					'interface_ref' => 'if5',
					'item_prototypes' => [
						[
							'name' => 'Drule Item SNMP v2',
							'type' => '20',
							'snmp_oid' => 'test',
							'interface_ref' => 'if5',
							'delay' => '1m',
							'history' => '31d',
							'trends' => '365d',
							'status' => '0',
							'discover' => '0',
							'value_type' => '3',
							'units' => '',
							'description' => '',
							'tags' => [],
							'valuemap' => [],
							'preprocessing' => [],
							'timeout' => '',
							'key_' => 'test8',
							'trigger_prototypes' => []
						]
					],
					'filter' => [
						'conditions' => [],
						'evaltype' => (string) CONDITION_EVAL_TYPE_AND_OR
					],
					'delay' => '1m',
					'status' => '0',
					'lifetime' => '30d',
					'description' => '',
					'trigger_prototypes' => [],
					'graph_prototypes' => [],
					'host_prototypes' => [],
					'lifetime_type' => (string) ZBX_LLD_DELETE_AFTER,
					'enabled_lifetime_type' => (string) ZBX_LLD_DELETE_NEVER,
					'lld_macro_paths' => [],
					'preprocessing' => [],
					'timeout' => '',
					'overrides' => [],
					'key_' => 'drule2'
				],
				'drule3' => [
					'name' => 'Discovery Rule 3',
					'type' => '20',
					'snmp_oid' => 'test',
					'interface_ref' => 'if7',
					'item_prototypes' => [
						[
							'name' => 'Drule Item SNMP v3',
							'type' => '20',
							'snmp_oid' => 'test',
							'interface_ref' => 'if9',
							'delay' => '1m',
							'history' => '31d',
							'trends' => '365d',
							'status' => '0',
							'discover' => '0',
							'value_type' => '3',
							'units' => '',
							'description' => '',
							'tags' => [],
							'valuemap' => [],
							'preprocessing' => [],
							'timeout' => '',
							'key_' => 'test9',
							'trigger_prototypes' => []
						]
					],
					'filter' => [
						'conditions' => [],
						'evaltype' => (string) CONDITION_EVAL_TYPE_AND_OR
					],
					'delay' => '1m',
					'status' => '0',
					'lifetime' => '30d',
					'description' => '',
					'trigger_prototypes' => [],
					'graph_prototypes' => [],
					'host_prototypes' => [],
					'lifetime_type' => (string) ZBX_LLD_DELETE_AFTER,
					'enabled_lifetime_type' => (string) ZBX_LLD_DELETE_NEVER,
					'lld_macro_paths' => [],
					'preprocessing' => [],
					'timeout' => '',
					'overrides' => [],
					'key_' => 'drule3'
				]
			]
		], $adapter->getDiscoveryRules());
	}

	public function testTemplateVendorFields() {
		$adapter = $this->getAdapter($this->getFile('vendor_fields.xml'));

		$this->assertEquals([
			[
				'groups' => [
					[
						'name' => 'Templates'
					]
				],
				'macros' => [],
				'templates' => [],
				'uuid' => '0c45e5ed44ea494dabfa4136f420aa65',
				'host' => 'vendor test',
				'name' => 'vendor test',
				'description' => '',
				'vendor_name' => 'Zabbix',
				'vendor_version' => '6.4-0',
				'tags' => [],
				'valuemaps' => []
			]
		], $adapter->getTemplates());
	}

	public function testHostMonitoredBy(): void {
		$adapter = $this->getAdapter($this->getFile('hosts_monitored_by.xml'));

		$this->assertEquals([
			[
				'host' => 'host1',
				'name' => 'host1',
				'monitored_by' => '0', // ZBX_MONITORED_BY_SERVER
				'proxy' => [],
				'proxy_group' => [],
				'description' => '',
				'status' => '0',
				'ipmi_authtype' => '-1',
				'ipmi_privilege' => '2',
				'ipmi_username' => '',
				'ipmi_password' => '',
				'templates' => [],
				'groups' => [
					[
						'name' => 'Hosts'
					]
				],
				'interfaces' => [],
				'tags' => [],
				'macros' => [],
				'inventory' => [],
				'inventory_mode' => '-1',
				'valuemaps' => []
			],
			[
				'host' => 'host2',
				'name' => 'host2',
				'monitored_by' => '1', // ZBX_MONITORED_BY_PROXY
				'proxy' => [
					'name' => 'Proxy'
				],
				'proxy_group' => [],
				'description' => '',
				'status' => '0',
				'ipmi_authtype' => '-1',
				'ipmi_privilege' => '2',
				'ipmi_username' => '',
				'ipmi_password' => '',
				'templates' => [],
				'groups' => [
					[
						'name' => 'Hosts'
					]
				],
				'interfaces' => [],
				'tags' => [],
				'macros' => [],
				'inventory' => [],
				'inventory_mode' => '-1',
				'valuemaps' => []
			],
			[
				'host' => 'host3',
				'name' => 'host3',
				'monitored_by' => '2', // ZBX_MONITORED_BY_PROXY_GROUP
				'proxy' => [],
				'proxy_group' => [
					'name' => 'Proxy group'
				],
				'description' => '',
				'status' => '0',
				'ipmi_authtype' => '-1',
				'ipmi_privilege' => '2',
				'ipmi_username' => '',
				'ipmi_password' => '',
				'templates' => [],
				'groups' => [
					[
						'name' => 'Hosts'
					]
				],
				'interfaces' => [],
				'tags' => [],
				'macros' => [],
				'inventory' => [],
				'inventory_mode' => '-1',
				'valuemaps' => []
			]
		], $adapter->getHosts());
	}

	protected function getAdapter($source) {
		$reader = CImportReaderFactory::getReader(CImportReaderFactory::XML);
		$source = $reader->read($source);

		$import_validator_factory = new CImportValidatorFactory(CImportReaderFactory::XML);
		$import_converter_factory = new CImportConverterFactory();

		$validator = new CXmlValidator($import_validator_factory, CImportReaderFactory::XML);

		$source = $validator
			->setStrict(true)
			->validate($source, '/');

		foreach ($import_converter_factory::getSequentialVersions() as $version) {
			if ($source['zabbix_export']['version'] !== $version) {
				continue;
			}

			$source = $import_converter_factory
				->getObject($version)
				->convert($source);

			$source = $validator
				->setStrict(false)
				->validate($source, '/');
		}

		$schema = (new CImportValidatorFactory('xml'))->getObject(ZABBIX_EXPORT_VERSION)->getSchema();

		$source = (new CConstantImportConverter($schema))->convert($source);
		$source = (new CDefaultImportConverter($schema))->convert($source);
		$source = (new CImportDataNormalizer($schema))->normalize($source);

		$adapter = new CImportDataAdapter();
		$adapter->load($source);

		return $adapter;
	}

	protected function get18Xml() {
		return $this->getFile('host18.xml');
	}

	protected function getEmptyXml() {
		return '<?xml version="1.0" encoding="UTF-8"?>
			<zabbix_export>
				<version>2.0</version>
				<date>2014-11-14T09:41:02Z</date>
			</zabbix_export>';
	}

	protected function getHostAndTemplateXml() {
		return $this->getFile('hostAndTemplate.xml');
	}

	protected function getMapXml() {
		return $this->getFile('map.xml');
	}

	protected function getMediaTypeXml() {
		return $this->getFile('mediatype.xml');
	}

	protected function get10Xml() {
		return $this->getFile('schema_1.0.xml');
	}

	/**
	 * Get XML with Template SNMP items.
	 */
	protected function getSNMPTemplateXml() {
		return $this->getFile('SNMP_items_templates.xml');
	}

	protected function getSNMPHostXml() {
		return $this->getFile('SNMP_items_hosts.xml');
	}

	protected function getFile($name) {
		if (!isset($this->sources[$name])) {
			$this->sources[$name] = file_get_contents(__DIR__.'/xml/'.$name);
		}

		return $this->sources[$name];
	}
}
