/*
 * 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.
 */

//! Agent Graph business policy. Host execution and plugin lifecycle are separate authorities.
pub mod access;
pub mod control;
pub mod coordinator;
pub mod decision;
pub mod owner;
pub mod projection;
pub mod repository;
pub mod schedule;
pub mod settings;
pub mod store;
pub mod swarm;
pub mod view;

use serde::{Deserialize, Serialize};

#[derive(Debug, thiserror::Error)]
pub enum Error {
    #[error("invalid Agent Graph input: {0}")]
    Invalid(String),
    #[error("Agent Graph is closed")]
    Closed,
    #[error("Agent Graph revision changed")]
    Conflict,
    #[error("Agent Graph item not found: {0}")]
    NotFound(String),
    #[error("Agent Graph decision outcome is unknown: {0}")]
    OutcomeUnknown(String),
    #[error("Agent Graph persistence failed: {0}")]
    Persistence(String),
    #[error(transparent)]
    Storage(#[from] maka_capabilities::storage::StoreError),
    #[error(transparent)]
    Host(#[from] maka_capabilities::authorization::CommandError),
}

pub fn identity(value: &str) -> Result<(), Error> {
    if value.is_empty() || value.trim() != value || value.chars().any(char::is_control) {
        return Err(Error::Invalid("invalid identity".into()));
    }
    Ok(())
}

macro_rules! id {
    ($ty:ident, $prefix:literal) => {
        #[derive(
            Clone,
            Debug,
            PartialEq,
            Eq,
            PartialOrd,
            Ord,
            Serialize,
            Deserialize,
            schemars::JsonSchema,
        )]
        #[serde(try_from = "String", into = "String")]
        #[schemars(with = "String", extend("minLength" = 1))]
        pub struct $ty(String);

        impl $ty {
            pub fn new() -> Self {
                Self(format!("{}{}", $prefix, uuid::Uuid::new_v4().simple()))
            }
            pub fn as_str(&self) -> &str {
                &self.0
            }
        }
        impl Default for $ty {
            fn default() -> Self {
                Self::new()
            }
        }
        impl TryFrom<String> for $ty {
            type Error = Error;
            fn try_from(value: String) -> Result<Self, Error> {
                identity(&value)?;
                if !value.starts_with($prefix) {
                    return Err(Error::Invalid(concat!("invalid ", stringify!($ty)).into()));
                }
                Ok(Self(value))
            }
        }
        impl From<$ty> for String {
            fn from(id: $ty) -> Self {
                id.0
            }
        }
        impl std::fmt::Display for $ty {
            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
                f.write_str(&self.0)
            }
        }
    };
}

id!(GraphId, "agent_graph_");
id!(WorkId, "graph_work_");
id!(OperatorId, "graph_operator_");

#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize, schemars::JsonSchema)]
#[serde(rename_all = "snake_case")]
#[schemars(rename = "GraphMode")]
pub enum Mode {
    Graph,
    Swarm,
}

#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, schemars::JsonSchema)]
#[serde(rename_all = "camelCase", deny_unknown_fields)]
#[schemars(rename = "GraphEpoch")]
pub struct Epoch {
    pub root_session_id: String,
    pub epoch: u64,
    pub graph_id: GraphId,
    pub created_at: u64,
    pub mode: Mode,
}

impl Epoch {
    pub fn validate(&self) -> Result<(), Error> {
        identity(&self.root_session_id)?;
        if self.epoch == 0 || self.epoch > (1 << 53) - 1 || self.created_at > (1 << 53) - 1 {
            return Err(Error::Invalid("invalid graph epoch or time".into()));
        }
        Ok(())
    }
}
