"""
SGB v2 - the six context conditions (arms).

A  schema      : raw tables only. What an agent gets by default.
B  prose       : raw tables + a wiki page written the way companies actually write them
                 (incomplete, no owner, no dates, one paragraph contradicting another).
E  prose_full  : raw tables + prose that contains EXACTLY the same facts as arm C
                 (windows, change dates, formulas, owners, calendars) but as flowing
                 documentation, without machine-readable records or version fields.
                 This separates "the information was supplied" from "the information
                 was supplied as versioned structured records".
C  vercy       : raw tables + versioned definition records.
F  vercy_pad   : C + inert padding matched to the length and position of the federation
                 block. Separates context-length effects from federation content.
D  vercy_fed   : C + federation records naming the governing definition per exchange.

v2 changes after external review:
  - federation records apply to counterparty-facing questions only, and say so; internal
    reporting is explicitly excluded even when the rows belong to the contract
  - federation records carry effective dates
  - arms E and F added as controls
"""

ARMS = ["schema", "prose", "prose_full", "vercy", "vercy_pad", "vercy_fed"]

SCHEMA_NOTE = """\
# context
No definition catalogue is available. Use the table columns as given.
"""

# ---------------------------------------------------------------- arm B
PROSE_DOC = """\
# Meridian Supply Co - Data and Reporting Notes (internal wiki)

## Customers
We track every company we sell to in the customers table. A customer is considered
active when they have bought from us recently. Sales reviews the active list every
quarter. Note that some customers keep an open contract without ordering, and the
commercial team usually still counts those as part of the base.

Elsewhere in this wiki the active base is described as customers who ordered in the
past year, which is the definition the old quarterly pack used.

## Revenue
Revenue is the total sales value we booked in a period. Freight is recharged to the
customer and tax is collected on behalf of the state. Returns reduce what we actually
earned. Finance and Sales occasionally quote different revenue numbers for the same
month, usually because of timing.

## Delivery
An order counts as delivered when the customer receives it. The carrier also records
its own scan when the parcel leaves the hub, and that scan is what our logistics
partners report against.

## On-time performance
On-time means we met the delivery date we promised. Where a date has been renegotiated
with the customer, operations track against the agreed date instead.

## Suppliers
Halden Logistics handles a large share of our shipments under a framework contract.
Halden reports its own delivery and value figures, which do not always match ours.

## Business days
Working days exclude weekends and public holidays.
"""

# ---------------------------------------------------------------- arm E
# Same facts as arm C, written as documentation rather than as records.
PROSE_FULL = """\
# Meridian Supply Co - Reporting Handbook (complete edition)

## Active customers
Sales Operations owns this measure. A customer counts as active as of a given date if
that customer has at least one order whose status is not cancelled and whose order date
falls in the window ending on that date. From 1 January 2025 until 31 March 2026 the
window was 365 days. From 1 April 2026 onwards the window is 180 days. When a question
asks about a date in the past, use the window that was in force on that date, not the
current one. An open contract on its own does not make a customer active.

## Net revenue
The Financial Controller owns this measure and it changed once. Net revenue for a period
is the sum, over invoices dated inside the period, of the invoiced order's gross amount
minus its discount amount. Tax is always excluded, so the invoice face value is never the
figure to use. Freight was excluded from 1 January 2025 until 30 April 2026, and is
included from 1 May 2026 onwards. From that sum, subtract the amount of any returns dated
inside the same period. A question about a past period uses the treatment in force then.

## Delivered shipments
Customer Operations owns this and it has not changed since 1 January 2025. For Meridian
reporting a shipment counts as delivered as of a date if the customer confirmation date
is present and falls on or before that date. Halden Logistics uses a different rule for
its own reporting: since 1 January 2026 Halden treats a shipment as delivered when the
carrier scan date is present and on or before the date in question.

## On-time delivery
The Chief Operating Officer owns this measure and it changed once. From 1 January 2025
until 31 January 2026 a delivered shipment was on time if its delivery date fell on or
before the promised date recorded on the order. From 1 February 2026 onwards a delivered
shipment is on time if its delivery date falls on or before the revised promised date
when that field is populated, and otherwise on or before the promised date. As with the
active window, a question about a past date should use the rule in force on that date.

## Order value
The Financial Controller owns this and it has not changed since 1 January 2025. For
Meridian, order value is the gross amount minus the discount amount, with freight and
tax both excluded. Halden calculates the same thing differently for its own commercial
reporting: gross amount minus discount amount plus freight, with tax excluded.

## Business days
A Meridian business day is a weekday that is not a Meridian public holiday. The Meridian
holidays in 2026 are 1 January, 25 March, 10 April, 13 April, 1 May, 1 June, 15 August
and 1 October. Halden keeps its own calendar; its 2026 holidays are 1 January, 6 January,
3 April, 6 April, 1 May, 8 June, 15 August and 26 December. Customer Operations owns the
Meridian calendar and Halden's operations director owns theirs.
"""

# ---------------------------------------------------------------- arm C
VERCY_CORE = """\
# context: definition catalogue (machine readable)
# Each record is a definition with an owner, a version and an effective date.
# When a question is asked "as of" a date, the version in force on that date applies.

- id: meridian.def.active_customer
  version: 1
  effective_from: 2025-01-01
  effective_to: 2026-03-31
  owner: Head of Sales Operations
  statement: A customer is active as of date D if at least one order exists for that
    customer with status not equal to cancelled and order_date in the interval
    (D - window_days, D].
  parameters: {window_days: 365}
  scope: meridian

- id: meridian.def.active_customer
  version: 2
  effective_from: 2026-04-01
  supersedes: version 1
  owner: Head of Sales Operations
  statement: A customer is active as of date D if at least one order exists for that
    customer with status not equal to cancelled and order_date in the interval
    (D - window_days, D].
  parameters: {window_days: 180}
  scope: meridian

- id: meridian.def.net_revenue
  version: 1
  effective_from: 2025-01-01
  effective_to: 2026-04-30
  owner: Financial Controller
  statement: Net revenue for a period is the sum over invoices dated in the period of
    (gross_amount - discount_amount) of the invoiced order, excluding freight_amount
    and tax_amount, minus the amount of returns dated in the same period.
  scope: meridian

- id: meridian.def.net_revenue
  version: 2
  effective_from: 2026-05-01
  supersedes: version 1
  owner: Financial Controller
  statement: Net revenue for a period is the sum over invoices dated in the period of
    (gross_amount - discount_amount + freight_amount) of the invoiced order, excluding
    tax_amount, minus the amount of returns dated in the same period.
  scope: meridian

- id: meridian.def.delivered
  version: 1
  effective_from: 2025-01-01
  owner: Head of Customer Operations
  statement: A shipment is delivered as of date D if customer_confirm_date is present
    and is on or before D.
  scope: meridian

- id: meridian.def.on_time
  version: 1
  effective_from: 2025-01-01
  effective_to: 2026-01-31
  owner: Chief Operating Officer
  statement: A delivered shipment is on time if its delivery date is on or before the
    promised_date recorded on the order.
  scope: meridian

- id: meridian.def.on_time
  version: 2
  effective_from: 2026-02-01
  supersedes: version 1
  owner: Chief Operating Officer
  statement: A delivered shipment is on time if its delivery date is on or before
    revised_promised_date when that field is present, otherwise on or before
    promised_date.
  scope: meridian

- id: meridian.def.order_value
  version: 1
  effective_from: 2025-01-01
  owner: Financial Controller
  statement: Order value is gross_amount minus discount_amount. Freight and tax are
    excluded.
  scope: meridian

- id: meridian.def.business_day
  version: 1
  effective_from: 2025-01-01
  owner: Head of Customer Operations
  statement: A business day is a weekday that is not a Meridian public holiday.
  parameters: {holidays_2026: [2026-01-01, 2026-03-25, 2026-04-10, 2026-04-13,
    2026-05-01, 2026-06-01, 2026-08-15, 2026-10-01]}
  scope: meridian

- id: halden.def.delivered
  version: 2
  effective_from: 2026-01-01
  owner: Halden Logistics, Operations Director
  statement: A shipment is delivered as of date D if carrier_scan_date is present and
    is on or before D.
  scope: halden

- id: halden.def.order_value
  version: 1
  effective_from: 2025-01-01
  owner: Halden Logistics, Commercial Director
  statement: Order value is gross_amount minus discount_amount plus freight_amount.
    Tax is excluded.
  scope: halden

- id: halden.def.business_day
  version: 1
  effective_from: 2025-01-01
  owner: Halden Logistics, Operations Director
  statement: A business day is a weekday that is not a Halden public holiday.
  parameters: {holidays_2026: [2026-01-01, 2026-01-06, 2026-04-03, 2026-04-06,
    2026-05-01, 2026-06-08, 2026-08-15, 2026-12-26]}
  scope: halden
"""

# ---------------------------------------------------------------- arm D
FEDERATION_BLOCK = """\
# context: federation records (which side's definition governs an exchange)
#
# These records govern COUNTERPARTY-FACING questions only: reporting to the counterparty,
# reconciling with it, or invoicing under the named contract. Internal Meridian reporting
# is NOT covered by them, even when the rows involved belong to that contract. If a
# question is not counterparty-facing, meridian definitions apply.

- id: fed.C-118.delivered
  contract: C-118
  counterparty: halden
  effective_from: 2026-01-01
  applies_to: questions that reconcile with, or report delivery to, Halden Logistics
    under contract C-118
  does_not_apply_to: internal Meridian delivery reporting; any contract other than C-118,
    including contract C-301 which is also operated by supplier HAL
  governing_definition: halden.def.delivered
  pinned_version: 2

- id: fed.C-118.order_value
  contract: C-118
  counterparty: halden
  effective_from: 2025-01-01
  applies_to: value invoiceable to or by Halden Logistics under contract C-118
  does_not_apply_to: internal Meridian valuation; contract C-301; supplier ZEN
  governing_definition: halden.def.order_value
  pinned_version: 1

- id: fed.C-118.on_time
  contract: C-118
  counterparty: halden
  effective_from: 2026-01-01
  applies_to: on-time performance reported under contract C-118
  governing_definition: meridian.def.on_time
  pinned_version: version in force on the as-of date
  measured_against: the delivery date determined by fed.C-118.delivered

- id: fed.C-118.business_day
  contract: C-118
  counterparty: halden
  effective_from: 2025-01-01
  applies_to: business-day counts inside the Halden service level agreement
  governing_definition: halden.def.business_day
  pinned_version: 1
"""

# ---------------------------------------------------------------- arm F
# Inert padding matched to the federation block in length and position. It carries no
# information about delivery, valuation, calendars or organisational authority.
PADDING_BLOCK = """\
# context: appendix, storage and transport notes (no bearing on any definition)

- id: sys.note.retention
  statement: Table extracts are retained in the analytics zone for 36 months and then
    moved to cold storage. Cold storage restores complete within four hours.

- id: sys.note.encoding
  statement: All extracts are UTF-8 without a byte order mark. Dates are ISO 8601.
    Decimal separators are points. Empty cells denote a missing value, not zero.

- id: sys.note.refresh
  statement: The orders and shipments extracts refresh nightly at 02:10 local time.
    Invoices refresh at 02:40. Returns refresh weekly on Sunday.

- id: sys.note.identifiers
  statement: Order identifiers use the prefix O, shipments S, invoices I, returns R and
    customers C, each followed by a zero-padded three digit sequence.

- id: sys.note.lineage
  statement: Extracts are produced by the reporting pipeline from the operational store.
    Pipeline run identifiers are recorded in the job log and are not part of the extract.

- id: sys.note.access
  statement: Read access to the analytics zone is granted by group membership and is
    reviewed twice a year. Write access is restricted to the pipeline service account.

- id: sys.note.transport
  statement: Files move between zones over an internal channel with checksums verified
    on arrival. A failed checksum re-queues the file rather than dropping it.
"""


def context_for(arm):
    if arm == "schema":
        return SCHEMA_NOTE
    if arm == "prose":
        return PROSE_DOC
    if arm == "prose_full":
        return PROSE_FULL
    if arm == "vercy":
        return VERCY_CORE
    if arm == "vercy_pad":
        return VERCY_CORE + "\n" + PADDING_BLOCK
    if arm == "vercy_fed":
        return VERCY_CORE + "\n" + FEDERATION_BLOCK
    raise ValueError(arm)
