/*!
 * Copyright 2014 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import { DeleteCallback, GetConfig, Metadata, ServiceObject, ServiceObjectConfig } from '@google-cloud/common';
import { Change } from './change';
import { Record, RecordMetadata } from './record';
import { DNS, CreateZoneRequest, CreateZoneResponse, CreateZoneCallback } from '.';
import { Readable } from 'stream';
import { InstanceResponseCallback } from '@google-cloud/common';
import { GetResponse } from '@google-cloud/common/build/src/service-object';
/**
 * Config to set for the change.
 *
 * @typedef {object} CreateChangeRequest
 * @property {Record|Record[]} add {@link Record} objects to add to this zone.
 * @property {Record|Record[]} delete {@link Record} objects to delete
 *     from this zone. Be aware that the resource records here must match
 *     exactly to be deleted.
 */
export interface CreateChangeRequest {
    add?: Record | Record[];
    delete?: Record | Record[];
}
/**
 * @typedef {array} CreateChangeResponse
 * @property {Change} 0 A {@link Change} object.
 * @property {object} 1 The full API response.
 */
export type CreateChangeResponse = [Change, Metadata];
/**
 * @callback CreateChangeCallback
 * @param {?Error} err Request error, if any.
 * @param {?Change} change A {@link Change} object.
 * @param {object} apiResponse The full API response.
 */
export interface CreateChangeCallback {
    (err: Error | null, change?: Change, apiResponse?: Metadata): void;
}
/**
 * @typedef {array} DeleteZoneResponse
 * @property {object} 0 The full API response.
 */
export type DeleteZoneResponse = [Metadata];
/**
 * @callback DeleteZoneCallback
 * @param {?Error} err Request error, if any.
 * @param {object} apiResponse The full API response.
 */
export type DeleteZoneCallback = DeleteCallback;
export interface DeleteZoneConfig {
    force?: boolean;
}
export interface GetRecordsCallback {
    (err: Error | null, records?: Record[] | null, nextQuery?: {} | null, apiResponse?: Metadata): void;
}
export type GetRecordsResponse = [Record[], Metadata];
export interface GetRecordsRequest {
    autoPaginate?: boolean;
    maxApiCalls?: number;
    maxResults?: number;
    name?: string;
    pageToken?: string;
    type?: string;
    filterByTypes_?: {
        [index: string]: boolean;
    };
}
export interface GetZoneRequest extends CreateZoneRequest, GetConfig {
}
/**
 * Query object for listing changes.
 *
 * @typedef {object} GetChangesRequest
 * @property {boolean} [autoPaginate=true] Have pagination handled automatically.
 * @property {number} [maxApiCalls] Maximum number of API calls to make.
 * @property {number} [maxResults] Maximum number of items plus prefixes to
 *     return.
 * @property {string} [pageToken] A previously-returned page token
 *     representing part of the larger set of results to view.
 * @property {string} [sort] Set to 'asc' for ascending, and 'desc' for
 *     descending or omit for no sorting.
 */
export interface GetChangesRequest {
    autoPaginate?: boolean;
    maxApiCalls?: number;
    maxResults?: number;
    pageToken?: string;
    sort?: string;
    sortOrder?: string;
}
/**
 * @typedef {array} GetChangesResponse
 * @property {Change[]} 0 Array of {@link Change} instances.
 * @property {object} 1 The full API response.
 */
export type GetChangesResponse = [Change[], Metadata];
/**
 * @callback GetChangesCallback
 * @param {?Error} err Request error, if any.
 * @param {Change[]} changes Array of {@link Change} instances.
 * @param {object} apiResponse The full API response.
 */
export interface GetChangesCallback {
    (err: Error | null, changes?: Change[] | null, nextQuery?: {} | null, apiResponse?: Metadata): void;
}
/**
 * @typedef {array} ZoneExportResponse
 * @property {object} 0 The full API response.
 */
export type ZoneExportResponse = [Metadata];
/**
 * @callback ZoneExportCallback
 * @param {?Error} err Request error, if any.
 * @param {object} apiResponse The full API response.
 */
export interface ZoneExportCallback {
    (err: Error | null): void;
}
type Without<T, K> = {
    [P in Exclude<keyof T, K>]: T[P];
};
type ZoneServiceObject = new (config: ServiceObjectConfig) => Without<ServiceObject<Zone>, 'create' | 'delete' | 'get'>;
declare const ZoneServiceObject: ZoneServiceObject;
/**
 * A Zone object is used to interact with your project's managed zone. It will
 * help you add or delete records, delete your zone, and many other convenience
 * methods.
 *
 * @class
 *
 * @example
 * const {DNS} = require('@google-cloud/dns');
 * const dns = new DNS();
 *
 * const zone = dns.zone('zone-id');
 */
declare class Zone extends ZoneServiceObject {
    name: string;
    getRecordsStream: (query?: GetRecordsRequest | string | string[]) => Readable;
    getChangesStream: (query?: GetChangesRequest) => Readable;
    constructor(dns: DNS, name: string);
    create(config: CreateZoneRequest): Promise<CreateZoneResponse>;
    create(config: CreateZoneRequest, callback: CreateZoneCallback): void;
    get(config?: GetZoneRequest): Promise<GetResponse<Zone>>;
    get(callback: InstanceResponseCallback<Zone>): void;
    get(config: GetZoneRequest, callback: InstanceResponseCallback<Zone>): void;
    addRecords(records: Record | Record[]): Promise<CreateChangeResponse>;
    addRecords(records: Record | Record[], callback: CreateChangeCallback): void;
    /**
     * Create a reference to a {@link Change} object in this zone.
     *
     * @param {string} id The change id.
     * @returns {Change}
     *
     * @example
     * const {DNS} = require('@google-cloud/dns');
     * const dns = new DNS();
     * const zone = dns.zone('zone-id');
     * const change = zone.change('change-id');
     */
    change(id?: string): Change;
    createChange(config: CreateChangeRequest): Promise<CreateChangeResponse>;
    createChange(config: CreateChangeRequest, callback: CreateChangeCallback): void;
    delete(options?: DeleteZoneConfig): Promise<DeleteZoneResponse>;
    delete(callback: DeleteZoneCallback): void;
    delete(options: DeleteZoneConfig, callback: DeleteZoneCallback): void;
    deleteRecords(records?: Record | Record[] | string): Promise<CreateChangeResponse>;
    deleteRecords(callback: CreateChangeCallback): void;
    deleteRecords(records: Record | Record[] | string, callback: CreateChangeCallback): void;
    empty(): Promise<CreateChangeResponse | []>;
    empty(callback: CreateChangeCallback): void;
    export(localPath: string): Promise<ZoneExportResponse>;
    export(localPath: string, callback: ZoneExportCallback): void;
    getChanges(query?: GetChangesRequest): Promise<GetChangesResponse>;
    getChanges(callback: GetChangesCallback): void;
    getChanges(query: GetChangesRequest, callback: GetChangesCallback): void;
    getRecords(query?: GetRecordsRequest | string | string[]): Promise<GetRecordsResponse>;
    getRecords(callback: GetRecordsCallback): void;
    getRecords(query: GetRecordsRequest | string | string[], callback: GetRecordsCallback): void;
    import(localPath: string): Promise<CreateChangeResponse>;
    import(localPath: string, callback: CreateChangeCallback): void;
    /**
     * A {@link Record} object can be used to construct a record you want to
     * add to your zone, or to refer to an existing one.
     *
     * Note that using this method will not itself make any API requests. You will
     * use the object returned in other API calls, for example to add a record to
     * your zone or to delete an existing one.
     *
     * @param {string} type The type of record to construct or the type of record
     *     you are referencing.
     * @param {object} metadata The metadata of this record.
     * @param {string} metadata.name The name of the record, e.g.
     *     `www.example.com.`.
     * @param {string[]} metadata.data Defined in
     *     [RFC 1035, section 5](https://goo.gl/9EiM0e) and
     *     [RFC 1034, section 3.6.1](https://goo.gl/Hwhsu9).
     * @param {number} metadata.ttl Seconds that the resource is cached by
     *     resolvers.
     * @returns {Record}
     *
     * @example
     * const {DNS} = require('@google-cloud/dns');
     * const dns = new DNS();
     *
     * const zone = dns.zone('zone-id');
     *
     * //-
     * // Reference an existing record to delete from your zone.
     * //-
     * const oldARecord = zone.record('a', {
     *   name: 'example.com.',
     *   data: '1.2.3.4',
     *   ttl: 86400
     * });
     *
     * //-
     * // Construct a record to add to your zone.
     * //-
     * const newARecord = zone.record('a', {
     *   name: 'example.com.',
     *   data: '5.6.7.8',
     *   ttl: 86400
     * });
     *
     * //-
     * // Use these records together to create a change.
     * //-
     * zone.createChange({
     *   add: newARecord,
     *   delete: oldARecord
     * }, (err, change, apiResponse) => {});
     */
    record(type: string, metadata: RecordMetadata): Record;
    replaceRecords(recordType: string | string[], newRecords: Record | Record[]): Promise<CreateChangeResponse>;
    replaceRecords(recordType: string | string[], newRecords: Record | Record[], callback: CreateChangeCallback): void;
    deleteRecordsByType_(recordTypes: string[]): Promise<CreateChangeResponse>;
    deleteRecordsByType_(recordTypes: string[], callback: CreateChangeCallback): void;
}
/**
 * Reference to the {@link Zone} class.
 * @name module:@google-cloud/dns.Zone
 * @see Zone
 */
export { Zone };
