#!/usr/bin/env python3

# load_locations_from_etc_clusters.py
#

import json
import sys

import requests

import fuss_glpi


class Client(fuss_glpi.GLPIClient):
    def add_options(self, parser):
        parser.add_argument(
            "-c", "--clusters_file",
            default="/etc/clusters",
        )

    def read_etc_clusters(self):
        self.clusters = {}
        with open(self.args.clusters_file) as fp:
            for line in fp.readlines():
                items = line.split()
                self.clusters[items[0]] = items[1:]

    def create_location(self, cluster):
        url = (
            f"{self.api_url}/search/Location?"
            "withindexes=true&"
            f"criteria[0][field]={self.location_search_fields["name"]}&"
            "criteria[0][searchtype]=contains&"
            f"criteria[0][value]={cluster}"
        )
        r = requests.get(
            url,
            verify=self.ca_cert,
            headers=self.headers,
        )
        res = json.loads(r.content)
        if res["count"] == 0:
            # create location
            url = f"{self.api_url}/Location"
            data = {
                "input": {
                   "name": cluster,
                }
            }
            r = requests.post(
                url,
                verify=self.ca_cert,
                headers=self.headers,
                data=json.dumps(data),
            )
            if r.status_code == 201:
                res = json.loads(r.content)
                loc_id = res["id"]
            else:
                print(
                    "Could not create location",
                    r.request.body,
                    r.content,
                )
                sys.exit(1)
        else:
            # use existing location
            loc_id = list(json.loads(r.content)["data"].keys())[0]

        return loc_id

    def assign_location(self, loc_id, computer, location):
        url = (
            f"{self.api_url}/search/Computer?"
            "withindexes=true&"
            f"criteria[0][field]={self.computer_search_fields["name"]}&"
            "criteria[0][searchtype]=contains&"
            f"criteria[0][value]={computer}"
        )
        r = requests.get(
            url,
            verify=self.ca_cert,
            headers=self.headers,
        )
        res = json.loads(r.content)
        if res["count"] == 0:
            print("No computer found with hostname", computer)
            return
        elif res["count"] > 1:
            print("Multiple computers found with the same hostname", computer)
            return
        for c_id, c in res["data"].items():
            c_data = c
        if c_data[self.computer_search_fields["location"]] != loc_id:
            url = f"{self.api_url}/Computer/{c_id}"
            data = {
                "input": {
                    "locations_id": loc_id,
                }
            }
            r = requests.put(
                url,
                verify=self.ca_cert,
                headers=self.headers,
                data=json.dumps(data),
            )
            if b"Location updated" not in r.content:
                print(
                    "Failed updating location",
                    r.content
                )

    def run(self):
        self.get_token()
        self.discover_computer_search_codes()
        self.discover_location_search_codes()
        self.read_etc_clusters()
        for cluster, computers in self.clusters.items():
            location_id = self.create_location(cluster)
            for c in computers:
                self.assign_location(location_id, c, cluster)


if __name__ == "__main__":
    Client().run()
