"""Five local HTTP requests with chosen query labels. No ad-platform lookup.

Run with Python 3.10+: python3 gclid-provenance-lab.py
No URL arguments, proxies, credentials, external connections or report files.
"""
import json
import threading
from http.client import HTTPConnection
from http.server import BaseHTTPRequestHandler, HTTPServer
from socketserver import TCPServer
from urllib.parse import parse_qsl, urlsplit


class LoopbackServer(HTTPServer):
    def server_bind(self):
        TCPServer.server_bind(self)
        self.server_name = '127.0.0.1'
        self.server_port = self.server_address[1]


def run():
    received = []

    class Handler(BaseHTTPRequestHandler):
        def log_message(self, *_):
            pass

        def do_GET(self):
            path = urlsplit(self.path)
            if path.path != '/offer':
                self.send_error(404)
                return
            values = [value for key, value in parse_qsl(path.query, keep_blank_values=True) if key == 'gclid']
            received.append({'path': self.path, 'gclid_values': values, 'observation': 'missing' if not values else 'single-label' if len(values) == 1 and values[0] else 'ambiguous-or-empty'})
            body = b'Local transport only; no advertising or measurement tags.\n'
            self.send_response(200)
            self.send_header('Content-Type', 'text/plain; charset=utf-8')
            self.send_header('Content-Length', str(len(body)))
            self.end_headers()
            self.wfile.write(body)

    cases = [
        ('no_label', '/offer'),
        ('chosen_label', '/offer?gclid=local_example_A'),
        ('repeated_label', '/offer?gclid=local_example_A'),
        ('another_label', '/offer?gclid=local_example_B'),
        ('duplicate_parameter', '/offer?gclid=local_example_A&gclid=local_example_B'),
    ]
    server = LoopbackServer(('127.0.0.1', 0), Handler)
    thread = threading.Thread(target=server.serve_forever, daemon=True)
    thread.start()
    try:
        for name, path in cases:
            connection = HTTPConnection('127.0.0.1', server.server_port, timeout=5)
            try:
                connection.request('GET', path)
                response = connection.getresponse()
                response.read()
                received[-1].update({'case': name, 'http_status': response.status})
            finally:
                connection.close()
    finally:
        server.shutdown()
        server.server_close()
        thread.join(timeout=5)
    single = [row['gclid_values'][0] for row in received if row['observation'] == 'single-label']
    return {'mode': 'loopback-http-with-client-chosen-labels', 'observations': received, 'request_rows': len(received), 'single_label_rows': len(single), 'distinct_single_labels': len(set(single)), 'ambiguous_rows': sum(row['observation'] == 'ambiguous-or-empty' for row in received), 'account_lookup_executed': False, 'ad_platform_requests': 0}


if __name__ == '__main__':
    print(json.dumps(run(), indent=2))
