'''
'''
#  Licensed to the Apache Software Foundation (ASF) under one
#  or more contributor license agreements.  See the NOTICE file
#  distributed with this work for additional information
#  regarding copyright ownership.  The ASF licenses this file
#  to you 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 json
import os

import trlib.ipconstants as IPConstants
from ports import get_port


# AddRecord registers a list of ip address against hostname
def AddRecord(hostname, list_ip_addr):

    record = dict()
    record[hostname] = list_ip_addr
    return record


# dict in format {'domain': [IPs]}
# json file in the same mappings/otherwise format that uDNS takes


def addRecords(self, records=None, jsonFile=None):
    jsondata = None

    # at this point the default file and fields should have been created
    if os.path.exists(self.Variables.zone_file):
        with open(self.Variables.zone_file, 'r') as f:
            jsondata = json.load(f)
    else:
        raise FileNotFoundError("default zone file doesn't exist, but it should.")

    if records:
        for domain in records:
            # Let's do this for the test writer's convenience.
            normalized_domain = domain
            if normalized_domain[-1] != '.':
                normalized_domain += '.'
            record = AddRecord(normalized_domain, records[domain])

            jsondata["mappings"].append(record)

    if jsonFile:
        jsonFile = os.path.join(self.TestDirectory, jsonFile)
        self.Setup.Copy(jsonFile, self.Variables.DataDir)

        with open(jsonFile, 'r') as f:
            entries = json.load(f)

            if entries:
                # not copying over entries['otherwise']. dont see the need to
                for record in entries["mappings"]:
                    jsondata["mappings"].append(record)

    with open(self.Variables.zone_file, 'w+') as f:
        f.write(json.dumps(jsondata))


def MakeDNServer(obj, name, filename="dns_file.json", port=False, ip='INADDR_LOOPBACK', rr=False, default=None, options={}):
    data_dir = os.path.join(obj.RunDirectory, name)
    filepath = os.path.join(data_dir, filename)
    obj.Variables.zone_file = filepath

    # provided file doesn't exist, so we create it and fill it in with the 'otherwise' values
    if not os.path.exists(os.path.dirname(filepath)):
        os.makedirs(os.path.dirname(filepath))

        jsondata = {'mappings': []}

        if default:
            if isinstance(default, str):
                # MicroDNS expects 'otherwise' to be a sequence.
                default = [default]
            jsondata['otherwise'] = default

        with open(filepath, 'w') as f:
            f.write(json.dumps(jsondata))

    # create Process
    p = obj.Processes.Process(name)
    if (port == False):
        port = get_port(p, "Port")
    command = "microdns {0} {1} {2}".format(ip, port, filepath)

    if rr:
        command += " --rr"

    # create process
    p.Command = command
    p.Setup.MakeDir(data_dir)
    p.Variables.DataDir = data_dir
    p.ReturnCode = 0

    if IPConstants.isIPv6(ip):
        p.Ready = When.PortOpenv6(port)
    else:
        p.Ready = When.PortOpenv4(port)

    AddMethodToInstance(p, AddRecord)
    AddMethodToInstance(p, addRecords)

    return p


ExtendTestRun(MakeDNServer, name="MakeDNServer")
ExtendTestRun(MakeDNServer, name="MakeDNS")
ExtendTest(MakeDNServer, name="MakeDNServer")
ExtendTest(MakeDNServer, name="MakeDNS")
