text: import {
      Zondy
  } from '../../common/Base';
  import {readHref} from './XLink';
  import XML from './XML';
  import {readString} from './xsd';
  import {
      makeObjectPropertyPusher,
      makeObjectPropertySetter,
      makeStructureNS,
      pushParseAndPop
  }from './base/xml';
  
  /**
   * @private
   * @const NAMESPACE_URIS 命名空间标识
   * @type {Array<null|string>}
   */
  const NAMESPACE_URIS = [null, 'http://www.opengis.net/ows/1.1'];
  
  /**
   * @private
   * @const PARSERS
   * @type {Object<string, Object<string>>}
   */
  const PARSERS = makeStructureNS(
      NAMESPACE_URIS, {
          'ServiceIdentification': makeObjectPropertySetter(readServiceIdentification),
          'ServiceProvider': makeObjectPropertySetter(readServiceProvider),
          'OperationsMetadata': makeObjectPropertySetter(readOperationsMetadata)
      });
  
  /**
   * @private
   * @classdesc 用于读取OWS数据的类
   */
  class OWS extends XML {
      constructor() {
          super();
      }
  
      /**
       * @private
       * @function Zondy.Format.OWS.prototype.readFromDocument
       * @description 从文档中读取信息，继承于父类XML
       * @return {owsObject|null}
       */
      readFromDocument(doc) {
          for (let n = doc.firstChild; n; n = n.nextSibling) {
              if (n.nodeType == Node.ELEMENT_NODE) {
                  return this.readFromNode(n);
              }
          }
          return null;
      }
  
      /**
       * @private
       * @function Zondy.Format.OWS.prototype.readFromNode
       * @description 从文档节点中读取信息，继承于父类XML
       * @return {owsObject|null}
       */
      readFromNode(node) {
          const owsObject = pushParseAndPop({},
              PARSERS, node, []);
          return owsObject ? owsObject : null;
      }
  }
  
  /**
   * @private
   * @const ADDRESS_PARSERS
   * @type {Object<string, Object<string>>}
   */
  const ADDRESS_PARSERS = makeStructureNS(
      NAMESPACE_URIS, {
          'DeliveryPoint': makeObjectPropertySetter(readString),
          'City': makeObjectPropertySetter(readString),
          'AdministrativeArea': makeObjectPropertySetter(readString),
          'PostalCode': makeObjectPropertySetter(readString),
          'Country': makeObjectPropertySetter(readString),
          'ElectronicMailAddress': makeObjectPropertySetter(readString)
      });
  
  /**
   * @private
   * @const ALLOWED_VALUES_PARSERS
   * @type {Object<string, Object<string>>}
   */
  const ALLOWED_VALUES_PARSERS = makeStructureNS(
      NAMESPACE_URIS, {
          'Value': makeObjectPropertyPusher(readValue)
      });
  
  /**
   * @private
   * @const CONSTRAINT_PARSERS
   * @type {Object<string, Object<string>>}
   */
  const CONSTRAINT_PARSERS = makeStructureNS(
      NAMESPACE_URIS, {
          'AllowedValues': makeObjectPropertySetter(readAllowedValues)
      });
  
  /**
   * @private
   * @const CONTACT_INFO_PARSERS
   * @type {Object<string, Object<string>>}
   */
  const CONTACT_INFO_PARSERS = makeStructureNS(
      NAMESPACE_URIS, {
          'Phone': makeObjectPropertySetter(readPhone),
          'Address': makeObjectPropertySetter(readAddress)
      });
  
  /**
   * @private
   * @const DCP_PARSERS
   * @type {Object<string, Object<string>>}
   */
  const DCP_PARSERS = makeStructureNS(
      NAMESPACE_URIS, {
          'HTTP': makeObjectPropertySetter(readHttp)
      });
  
  /**
   * @private
   * @const HTTP_PARSERS
   * @type {Object<string, Object<string>>}
   */
  const HTTP_PARSERS = makeStructureNS(
      NAMESPACE_URIS, {
          'Get': makeObjectPropertyPusher(readGet),
          'Post': undefined // TODO
      });
  
  /**
   * @private
   * @const OPERATION_PARSERS
   * @type {Object<string, Object<string>>}
   */
  const OPERATION_PARSERS = makeStructureNS(
      NAMESPACE_URIS, {
          'DCP': makeObjectPropertySetter(readDcp)
      });
  
  /**
   * @private
   * @const OPERATIONS_METADATA_PARSERS
   * @type {Object<string, Object<string>>}
   */
  const OPERATIONS_METADATA_PARSERS = makeStructureNS(
      NAMESPACE_URIS, {
          'Operation': readOperation
      });
  
  /**
   * @private
   * @const PHONE_PARSERS
   * @type {Object<string, Object<string>>}
   */
  const PHONE_PARSERS = makeStructureNS(
      NAMESPACE_URIS, {
          'Voice': makeObjectPropertySetter(readString),
          'Facsimile': makeObjectPropertySetter(readString)
      });
  
  /**
   * @private
   * @const REQUEST_METHOD_PARSERS
   * @type {Object<string, Object<string>>}
   */
  const REQUEST_METHOD_PARSERS = makeStructureNS(
      NAMESPACE_URIS, {
          'Constraint': makeObjectPropertyPusher(readConstraint)
      });
  
  /**
   * @private
   * @const SERVICE_CONTACT_PARSERS
   * @type {Object<string, Object<string>>}
   */
  const SERVICE_CONTACT_PARSERS =
      makeStructureNS(
          NAMESPACE_URIS, {
              'IndividualName': makeObjectPropertySetter(readString),
              'PositionName': makeObjectPropertySetter(readString),
              'ContactInfo': makeObjectPropertySetter(readContactInfo)
          });
  
  /**
   * @private
   * @const SERVICE_IDENTIFICATION_PARSERS
   * @type {Object<string, Object<string>>}
   */
  const SERVICE_IDENTIFICATION_PARSERS =
      makeStructureNS(
          NAMESPACE_URIS, {
              'Abstract': makeObjectPropertySetter(readString),
              'AccessConstraints': makeObjectPropertySetter(readString),
              'Fees': makeObjectPropertySetter(readString),
              'Title': makeObjectPropertySetter(readString),
              'ServiceTypeVersion': makeObjectPropertySetter(readString),
              'ServiceType': makeObjectPropertySetter(readString)
          });
  
  /**
   * @private
   * @const SERVICE_PROVIDER_PARSERS
   * @type {Object<string, Object<string>>}
   */
  const SERVICE_PROVIDER_PARSERS =
      makeStructureNS(
          NAMESPACE_URIS, {
              'ProviderName': makeObjectPropertySetter(readString),
              'ProviderSite': makeObjectPropertySetter(readHref),
              'ServiceContact': makeObjectPropertySetter(readServiceContact)
          });
  
  /**
   * @private
   * @function Zondy.Format.OWS.prototype.readAddress
   * @description 读取Address
   * @param {Element} node 节点.
   * @param {Array<*>} objectStack 对象堆栈.
   * @return {Object|undefined} The address.
   */
  function readAddress(node, objectStack) {
      return pushParseAndPop({},
          ADDRESS_PARSERS, node, objectStack);
  }
  
  /**
   * @private
   * @function Zondy.Format.OWS.prototype.readAllowedValues
   * @description 读取AllowedValues
   * @param {Element} node 节点.
   * @param {Array<*>} objectStack 对象堆栈.
   * @return {Object|undefined} The values.
   */
  function readAllowedValues(node, objectStack) {
      return pushParseAndPop({},
          ALLOWED_VALUES_PARSERS, node, objectStack);
  }
  
  /**
   * @private
   * @function Zondy.Format.OWS.prototype.readConstraint
   * @description 读取Constraint
   * @param {Element} node 节点.
   * @param {Array<*>} objectStack 对象堆栈.
   * @return {Object|undefined} The constraint.
   */
  function readConstraint(node, objectStack) {
      const name = node.getAttribute('name');
      if (!name) {
          return undefined;
      }
      return pushParseAndPop({
              'name': name
          },
          CONSTRAINT_PARSERS, node,
          objectStack);
  }
  
  /**
   * @private
   * @function Zondy.Format.OWS.prototype.readContactInfo
   * @description 读取ContactInfo
   * @param {Element} node 节点.
   * @param {Array<*>} objectStack 对象堆栈.
   * @return {Object|undefined} The contact info.
   */
  function readContactInfo(node, objectStack) {
      return pushParseAndPop({},
          CONTACT_INFO_PARSERS, node, objectStack);
  }
  
  /**
   * @private
   * @function Zondy.Format.OWS.prototype.readDcp
   * @description 读取Dcp
   * @param {Element} node 节点.
   * @param {Array<*>} objectStack 对象堆栈.
   * @return {Object|undefined} The DCP.
   */
  function readDcp(node, objectStack) {
      return pushParseAndPop({},
          DCP_PARSERS, node, objectStack);
  }
  
  /**
   * @private
   * @function Zondy.Format.OWS.prototype.readGet
   * @description 读取Get
   * @param {Element} node 节点.
   * @param {Array<*>} objectStack 对象堆栈.
   * @return {Object|undefined} The GET object.
   */
  function readGet(node, objectStack) {
      const href = readHref(node);
      if (!href) {
          return undefined;
      }
      return pushParseAndPop({
              'href': href
          },
          REQUEST_METHOD_PARSERS, node, objectStack);
  }
  
  /**
   * @private
   * @function Zondy.Format.OWS.prototype.readHttp
   * @description 读取Http
   * @param {Element} node 节点.
   * @param {Array<*>} objectStack 对象堆栈.
   * @return {Object|undefined} The HTTP object.
   */
  function readHttp(node, objectStack) {
      return pushParseAndPop({}, HTTP_PARSERS, node, objectStack);
  }
  
  /**
   * @private
   * @function Zondy.Format.OWS.prototype.readOperation
   * @description 读取Operation
   * @param {Element} node 节点.
   * @param {Array<*>} objectStack 对象堆栈.
   * @return {Object|undefined} The operation.
   */
  function readOperation(node, objectStack) {
      const name = node.getAttribute('name');
      const value = pushParseAndPop({},
          OPERATION_PARSERS, node, objectStack);
      if (!value) {
          return undefined;
      }
      const object = /** @type {Object} */
          (objectStack[objectStack.length - 1]);
      object[name] = value;
  }
  
  /**
   * @private
   * @function Zondy.Format.OWS.prototype.readOperationsMetadata
   * @description 读取OperationsMetadata
   * @param {Element} node 节点.
   * @param {Array<*>} objectStack 对象堆栈.
   * @return {Object|undefined} The operations metadata.
   */
  function readOperationsMetadata(node, objectStack) {
      return pushParseAndPop({},
          OPERATIONS_METADATA_PARSERS, node,
          objectStack);
  }
  
  /**
   * @private
   * @function Zondy.Format.OWS.prototype.readPhone
   * @description 读取Phone
   * @param {Element} node 节点.
   * @param {Array<*>} objectStack 对象堆栈.
   * @return {Object|undefined} The phone.
   */
  function readPhone(node, objectStack) {
      return pushParseAndPop({},
          PHONE_PARSERS, node, objectStack);
  }
  
  /**
   * @private
   * @function Zondy.Format.OWS.prototype.readServiceIdentification
   * @description 读取ServiceIdentification
   * @param {Element} node 节点.
   * @param {Array<*>} objectStack 对象堆栈.
   * @return {Object|undefined} The service identification.
   */
  function readServiceIdentification(node, objectStack) {
      return pushParseAndPop({}, SERVICE_IDENTIFICATION_PARSERS, node,
          objectStack);
  }
  
  /**
   * @private
   * @function Zondy.Format.OWS.prototype.readServiceContact
   * @description 读取ServiceContact
   * @param {Element} node 节点.
   * @param {Array<*>} objectStack 对象堆栈.
   * @return {Object|undefined} The service contact.
   */
  function readServiceContact(node, objectStack) {
      return pushParseAndPop({}, SERVICE_CONTACT_PARSERS, node,
          objectStack);
  }
  
  /**
   * @private
   * @function Zondy.Format.OWS.prototype.readServiceProvider
   * @description 读取ServiceProvider
   * @param {Element} node 节点.
   * @param {Array<*>} objectStack 对象堆栈.
   * @return {Object|undefined} The service provider.
   */
  function readServiceProvider(node, objectStack) {
      return pushParseAndPop({}, SERVICE_PROVIDER_PARSERS, node,
          objectStack);
  }
  
  /**
   * @private
   * @function Zondy.Format.OWS.prototype.readValue
   * @description 读取Value
   * @param {Node} node 节点.
   * @param {Array<*>} objectStack 对象堆栈.
   * @return {string|undefined} The value.
   */
  function readValue(node, objectStack) {
      return readString(node);
  }
  
  export default OWS;
  Zondy.Format.OWS = OWS;